March 17, 2015

Facebook Tweaks

Developers add many animations into their apps to make UI more intuitive and fun. Modern iOS has really nice API for view controller transitions and effects, Core Animation was there since the very beginning. More and more tools enable us to design and polish animation curves and fine-tune duration times or damping values.

From the earliest builds of Saver we started using the Tweaks library made by Facebook. Everything from custom view controller presentations to animation springs was wrapped into tweaks and then polished to death.

Despite its weird user interface, the Tweaks component does amazing job and we highly recommend it for iOS development. Below are minor improvements which may be useful for your project.

Replace the Shake gesture

By default, you open the Tweaks window using a Shake gesture. From our experience, this method is terrible. After 10-20 adjustments you will hate your iPhone and any animation parameters. So I replaced the FBTweakShakeWindow by custom implementation, to react on the quite fast re-activation.

So, instead of shaking the damn device, you press the Home button three times in a row. This works like a charm and you will never do this coincidentally.

Please find the full solution in the Gist. The methods applicationWillResignActive: and applicationDidBecomeActive: are essential.

Disable Tweaks in production

Development builds are different from the final product in the App Store. You do not want to provide macros with Release configuration, but there is one gotcha. Your teammate may be a designer or a product manager without Xcode. For example, we use Apple TestFlight for public Beta testing, but Hockey for internal builds.

Facebook library defines the symbol FB_TWEAK_ENABLED only when the symbol DEBUG is available. However, we need Tweaks in the Release build. So we duplicate the Hockey configuration from Release and add the following lines into the workspace Podfile.

post_install do |installer_representation|
    installer_representation.project.targets.each do |target|
        if == "Pods-Tweaks"
            target.build_configurations.each do |config|
                if == 'Hockey'
                    ||= ['$(inherited)', 'FB_TWEAK_ENABLED=1']

Execute pod install in the command-line to update Xcode project settings. Now Build Properties for the Hockey configuration will include the symbol FB_TWEAK_ENABLED and Tweaks panel will be available as result.

One hint to save your time

There is a small note I did not found in the official documentation for the component. Never try something like this:

#define MODAL_SCREEN_COLLECTION @"Modal Screen"
#define FADE_IN_GROUP @"Fade In"

First, these symbols pretty fast become unmanageable. Second, AppCode may not highlight things properly because you implicitly wrap one macro into another.

Instead, insert pure strings even if they are duplicates. The most likely, you will remove them in the end of the day, when animations are polished and just occupy too many rows in the Tweaks panel.

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)ctx
    return (self.movingBehind
            ? FBTweakValue(@"Modal Screen", @"Move Behind", @"Duration", 0.5)
            : FBTweakValue(@"Modal Screen", @"Restore", @"Duration", 0.4));

Happy tweaking!

March 10, 2015

How do you integrate Swift code into Objective-C?

I have switched to Swift recently. As result, new code for Saver is mostly written using faster enums and structs, locally-scoped extensions, super-lazy vars, safer let and switch statements, meaningful square brackets etc. Only bug fixes and minor changes not worth a separate file are still coded in Objective-C.

But there is a problem. I cannot think up a better way to incorporate global .swift functions into .m classes other than creating a “fake” @objc class with a class func which takes only one argument and usually returns void.

@objc class CalculatorLayout {
    class func placeIntoViewController(viewController: UIViewController) {
        let view = viewController.view
        for cell in calculatorCells {
            let button = buttonWithCell(cell)
#import "Saver-Swift.h"
@implementation SVRCalculatorViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    [CalculatorLayout placeIntoViewController:self];

This code definitely smells. I looked for possible solutions in Swift Documentation and on StackOverflow, but all tutorials and hints that I found recommend the right way only for “pure” object classes with regular methods.

So how do you deal with “value-typed” and other “non-OOP” Swift code in Objective-C projects?

February 25, 2014

9 Reasons to try AppCode for Objective-C coding

Different IDE for Cocoa development

AppCode is JetBrains’ alternative to Xcode. It was introduced in 2011 and became quite popular among Apple developers. There is no public data about Xcode vs AppCode downloads, but I assume the number of people who tried and use non-Apple software for iOS and Mac development is comparatively small.

I personally launched the trial of AppCode 1.5 only once, then later bought a discounted license for 2.0 because of too many recommendations in Twitter. Unfortunately, it always “looked like Java” and felt like something from 2000s surrounded by the modern interface of OS X. I tried to get used to it some times with no luck.

However, AppCode gets better with each release and acquires more and more fans in our community, so in 2014 I decided to give it a serious try before my yearly subscription license expires. Surprisingly, this resulted in full-time switching to the new IDE for coding in Objective-C.

I am still newbie but would like to share some things which were not obvious for me from the very beginning, demystify the hype, and maybe convince you to give another chance to this awesome development tool.

AppCode autocompletion in Action

1. The same project can be open in AppCode and Xcode simultaneously

There is no need to abandon Apple’s IDE when you “switch” to AppCode. I have Xcode running on the “home” OS X space and use it for debugging, creating new classes and editing project settings. In the second full-screen space I have the same Xcode project open in AppCode and use it purely for writing Objective-C code, for making changes to existing classes and sometimes for committing to the git repository.

2. You can totally customize AppCode to “dim” the look and feel of Java

For me, the default theme copied from Xcode looked horrible and heavy. However, everything can be customized to remove the distractions. For instance, I changed the code editor font, added line numbers, removed the code folding icons, hid the 100 characters gutter from the code editor, and disabled yellow highlighting on the “current” line.

Also, after the very first launch, you would better to close all utility windows, so that code editor feels like TextMate. After using AppCode for a while, you will meet each utility window in the right and neccessary context to understand and appreciate it. With time, all panels become “invisible” and non-distracting.

3. Renaming vars and methods in Objective-C code feels like magic

Xcode is great for refactoring, especially when you use Control-Command-E to rename the local variable or the local file method. But every time you call the command Rename… to change the class name globally, you become frustrated. You always fear the worst and relax only after everything ends up as expected. Then you double-check each change in the project and bless Xcode that it did not screw up anything. Right?

Renaming experience with AppCode is totally different. I mean it. You press Shift-F6, type the new name, press Enter, and immediately continue to type new code. Most of the times there is no single thought about incorrect changes that might happen. Mainly, because you don’t see the modal sheet re-asking if you really want to start refactoring.

4. Contextual code “moving” commands make refactoring a pleasure

There is always code that can be improved by moving things around, and there is always a reason to do this later. But in AppCode, moving code within and even between classes is so easy that you never skip this mini-refactoring “till later”.

For any code selection, there is always a contextual menu with commands which will try to improve your code. For example, if you keep the cursor on the method declaration in the public interface for a second, the small lightbulb may advise you to move the method into the private category.

You can select some methods and move them into the new class which makes the process of code decoupling much faster and easier. You can extract selected lines into the new method, function or block etc. These operations are performed in a simple and intuitive interface.

5. Code Inspection tool will make you sure that your code is clean

JetBrains’ IDE analyzes your code in LIVE mode to highlight unneccessary #import lines, unused public methods, to find unreachable code lines and other things that can be fixed to polish your Objective-C, C and C++ code.

Because of using the same llvm clang compiler, such code analysis is available in Xcode, but all warnings appear only after compilation. This feels okay only until you try AppCode.

I am not going to post the famous tweet with a screenshot where AppCode hints about the Apple’s goto fail; okay?

6. You can use advanced live templates to speed up coding

New @protocol for the class delegate, #pragma mark, dispatch_async and other snippets are useful in Xcode, but their implementation in AppCode is smarter and somehow more intuitive.

There are many examples of native and user-made scripts that you will like because of smart variables. And the more you use them, the more you want to expriment and play with your own collection i.e.

7. AppCode has a number of ways to autocomplete the whole methods

In Xcode, you have to type first letters of the new overriden method i.e. -tabl, then select from the huge list of names by scrolling to finally insert the right signature. In AppCode, you hit the command Implement…, select two or three methods at once and press Continue. Boom, and you have got 3-4 new methods with default implementation.

By the way, you can type a method which does not yet exist, then hit the command Create Method and confirm parameters to insert the new signature into the class implementation. How many times have you missed this in Xcode?

Overall, it seems like JetBrains tend to implement all the features you miss in Xcode even if they are not neccessary. Sometimes, it feels like a bad design and definitely not the Apple way to build things, but if you consider AppCode as Xcode complement, this is cool.

8. Integration with CocoaPods and syntax highlighting for Podfile

No comments. AppCode supports the syntax highlighting in Podfile. There is a hint when the local gem cocoapods must be updated to the latest new version together with a button Update. You have the primitive interface to avoid Terminal, and the simple GUI makes you feel in full control of submodules.

9. Advanced version control with terrific layout for merging

I like the simplicity of committing in Xcode, but it is not very convenient for overview after massive changes. AppCode’s interface looks not that good, but its advanced features like merging in three panes are very helping.

Conclusion that I needed three years to come up with

AppCode is not a replacemenet for Xcode. Consider it as one of many tools that you can use to improve your Cocoa development process.

Go to the official website, download the free trial, start using it, and do your best to keep up with minor annoyances for one week. You won’t regret.

P.S. AppCode has got problems. Yes, it is not perfect. But the Team rocks. I mean it. They fix bugs and implement many features fairly quick for the most part. Their official Twitter account gives prompt and humane responses to any requests. Give it a try :)

February 10, 2014

How to reduce Xcode and AppCode build times


Both Xcode and AppCode intensively cache temporary “information” on the file system. Each time you cleanup the project, make a new build, or launch the app in iOS Simulator, IDE will read and write megabytes of files into the special folder named DerivedData. You will be surprized how much space can be freed up by executing rm -rf ~/Library/Developer/Xcode/DerivedData/* in Terminal. This command is totally safe, because Xcode will regenerate everything it needs from scratch when you build the next project.

As result of this caching, the speed of building and launching the app in debugger may significantly depend on the “speed” of your hard drive. With SSD, a typical iOS-project with precompiled information will launch in 5-10 seconds. With HDD, it will take more time. Anyway, you should know that there is an easy way to build and launch the app in iOS Simulator much faster.

Free Solution

I found this solution in the Krzysztof ZabÅ‚ocki’s talk about iOS Developer Tools. The last paragraph of the article (it is not mentioned in the video) is about the command line tool named RamDisk:

This script will let you create ramdisk for iOS sim, derived data a few other important folders. This can make your development wayyy faster.

In other words, OS X allows you to create a super-fast file storage directly in RAM and hard-link it into the file system in place of the DerivedData folder used by Xcode. You can even create multiple “virtual” drives and mount them to Application Support/iPhone Simulator and Application Support/Caches/appCode2.0 to make these caches fast and truly temporary.

There is a great blog post explaining this in more details, and some are worth quotation:

Mounting a volume on top of your existing DerivedData hides the old files. They continue to take up space, but are unreachable until you unmount the RAM disk.

The contents of the RAM disk disappear when you reboot or eject it from the Finder. Xcode will need to rebuild its indexes and all of your project’s intermediate files the next time you create one.

One more thing: such RAM disks are not “allocated” in the memory, they take only as much space as needed to keep all files.

Update → AppCode does not recommend moving the whole Caches/appCode20 folder on a RAM disk, because among everything it stores indices and local history's data. Once the in-memory storage is reset, no local history will be available. However:

DerivedData can be safely moved to a ram disk; though for big projects the full rebuild may cost more than the saved time.

Paid Solution

Unfortunately, the original Gist does not support commands stop and start, so you will have to restart OS X in order to remove RAM disks. It is not very convenient to support them between launches and you can forget to reclaim the RAM after you finish the coding session.

Fortunately, “there is an app for that”. iRamDisk will create and manage RAM disks for you. There is a standard setup for Xcode development, and you can easily mount the caches folder used by AppCode too. Here is my setup:

AppCode RAM Settings in iRamDisk

Update → iRamDisk menu bar icon stands out of the croud, so I made a replacement. Put these images in /Applications/ and toggle the preference Show in menu bar to update.

Does it work?


I tried this on my MacBook Pro with Retina Display 8 GB and iOS Simulator launch time reduced to the matter of seconds. There is also a conversation in Twitter that you may find interesting.

It seems like the iOS Simulator launch time does not change significantly for AppCode, but I find it fascinating that SSD is not touched during massive cache readings and writings.

P.S. I assume the same recipe would work with Photoshop or Illustrator.

October 5, 2012

ResolutionTab 1.1 brings missed features

ResolutionTab was released one month ago and has been pretty successful for such a simple developer tool. It has got very positive feedback in the Mac App Store and was even reviewed at Lifehacker. After receiving your feedback and feature requests, I implemented some improvements to make this tool even more useful.

First, it turned out it is possible to enable the checkbox Launch at Login in the sandboxed environment. If you are a Cocoa developer and looking for information on this topic, the following resources should be useful: Start dockless apps at login with App Sandbox enabled, How to add a sandboxed app to the login items and Sandboxing, login items and launch App. All of these resources resulted in a new checkbox in the Preferences panel allowing to launch ResolutionTab automatically when you on log in.

Next, the menubar icon is usually invisible when an active app menu is too wide and you are working on a MacBook. To make switching still possible, the new version adds support for the global keyboard shortcut. Now there is no need to click the status icon. You define the hotkey and then press it in any app to switch from the standard display mode to HiDPI and vice versa. By the way, if you are developing Mac app and need a control for hotkeys, check out my GitHub project MASShortcut. Recent commits introduce new options for appearance of the input view.

In addition, the app now watches for recently used display modes and enables switching between the two most popular much easier by putting them into the main menu. This allows to return back to the previously selected resolution, even if it is not ultra-high, in one click or hotkey press.

Finally, not all users could find an Option-Click on the icon to switch between all available display modes. In the new update, the global menu is redesigned and now it has all available modes under the submenu. This will also make the app more convenient for MacBook Pro with Retina display. That's it.

Check out an update of ResolutionTab 1.1 in the Mac App Store.

August 22, 2012

ResolutionTab: switch between Standard and Retina modes in one click

Devices with Retina displays are the future. Apple introduced iPhone and iPad with double resolution screens a long time ago, but the small sizes allowed software makers to ignore @2x graphics. Things changed rapidly when Apple introduced the new MacBook Pro with a Retina display. Now you simply can't ignore ultrahigh-resolution displays when developing new software.

To help developers and designers with older Macs, Apple has added support for additional display modes (named HiDPI) in OS X 10.8. You have to install Xcode and launch its Quartz Debug tool to enable the virtual modes system-wide. Then you will be able to switch between standard and @2x graphics using the Displays pane in System Preferences. This is the way you can test how a website or an app will look on the modern devices.

When you configure your display in System Preferences however, it takes plenty of time to switch from the standard to HiDPI mode and vice versa. It would be much better if the process was automated or simplified in some way. And here we go.

ResolutionTab is a minimal app living in the menu bar. It allows you to switch between real and virtual display modes right from the menu bar. ResolutionTab requires OS X 10.8 and Xcode to enable virtual HiDPI modes in OS X.

Download in the Mac App Store

Special thanks to @solonsky, @gregdougherty, @pieteromvlee, @ruiaureliano and @philipbruce.

July 9, 2012

Global Keyboard Shortcuts in Cocoa

There is a lot of menu bar apps which display a panel with user interface when you click the menu bar icon. To make our life easier, these apps usually provide a global keyboard shortcut to access that panel without using your mouse.

Other apps just run in background and wait while you press a hotkey to perform some action. Evernote, Fantastical, Clocks, LittleSnapper, Things… all of these use global shortcuts to do their work. But how to implement this feature in you own Mac app?


Unfortunately, there is no official Cocoa API like NSGlobalShortcut. Instead, you have to deal with old low-level Carbon APIs to listen for global hotkeys, look here and here to find more details.

In addition, we would need a control like NSGlobalShortcutView to enter and display keyboard shortcuts with special characters for Command, Option and Shift, something like this.

From the links I just posted, you may find that adding support for global keyboard shortcuts is a non-trivial task. You have to dive into the component architecture, copy many sources or framework into your project, and finally add many lines of code into your app.


I always wanted to have something more lightweight and easy to use, something modern, something that will have simple APIs with blocks. And here we go, I would like to share a “framework” MASShortcut. I use it in my own apps CodeBox and Hunting, all code is compatible with latest OS X 10.7, with the Mac App Store and its sandboxed environment. So I hope you will find it useful :)


To use MASShortcut in a Cocoa app, git clone the repository from GitHub, link to the Carbon.framework in Xcode and drag all Objective-C files into your project. Then insert a custom view of 19 pixels height into XIB and set its class to MASShortcutView. Next, import "MASShortcutView+UserDefaults.h" into the view controller and ask the shortcut view to read and store a hotkey in user preferences automatically. That's it for the UI part.

To listen for the global hotkey stored in user preferences, you have to import "MASShortcut+UserDefaults.h" into the application delegate, for example. And then provide a block of code to execute when the user presses that global hotkey. This is really easy as you can see in README:

MASShortcut on GitHub

I built a simple application which demonstrates MASShortcut in action, please check MASShortcutDemo on GitHub and let me know if you have any questions or suggestions, — @vadimshpakovski in Twitter.