a hell of a lot easier to fix a bug when your networking code and your view layout code are not all mixed together. » Note that MVC can easily be replaced by MVVM - the goal of both patterns is to separate your model code from your view code from the code which updates both.
Inheritance is best used when you have many things of the same type that do the same thing. » For example, if all your UIViewControllers have a logout button in the UINavigationBar, use a superclass to add that button and handle logout. » If there's a bug with logout, there's only one place to look.
padding or sizes for UI elements, use CGFloat constants to enforce that. » Makes it way easier to read your code: self.viewWidth = 74; vs self.viewWidth = kProfileViewWidth; » If design changes up your padding, you change it in one place, and you're done.
great way to handle operations that are a little too convoluted to handle with methods. #define CDSELECTOR(selectorSymbol) NSStringFromSelector(@selector(selectorSymbol)) » Macros can easily be abused by being used where declared, typed Constants would make more sense. #define kStringConstant @"A String That Should Be A Constant"
for macro migration to Swift boils down to "don't": "Declare simple macros as global constants, and translate complex macros into functions." » You can use certain runtime definitions in Swift (#ifdef DEBUG), but there are a ton of restrictions. » If you're moving a project to Swift, find a way to use functions instead wherever possible.
about your project should be able to easily read your code. » Remember: Sometimes that person will be you in the future. » Fixing bugs is a lot easier to do when you can figure out what the hell you were trying to do in the first place just by reading code and comments.
*v, CGPoint pt » BETTER: UIView *profileView, CGPoint profileOrigin » This is especially important in Swift because of type inference - you want to be able to have someone reading your code tell what type a variable would be without having to scroll back up to where it was declared.
er:andCompletionBlock: » Swift can still doWhatItSaysOnTheLabel(). » The biggest difference is that in Swift, often you can leave off the parameter names in code, which can make the code harder to read. » Particularly for single-parameter methods, name your methods so that the type of the first parameter is very clear.
» Naming things clearly helps facilitate searching » By the name of a file » By the name of a property/method or by typing in the drop-down menu » Reading a stack trace is easier when you can follow names of methods. » Makes it easy to get a summary of what a file does from the drop-down menu.
you're letting the code do most of the talking for you in terms of what you're doing, and that you're using comments to clarify why you're taking a certain approach. » If you're using Some Code You Found On The Internet, throw in a link - sometimes old posts will get updated with links to new approaches. » If something is a workaround for an older version of iOS, note that in your comments so it can be removed once support for that version is dropped.
your user interface. » Really, really fast. Typical unit tests take < 1 minute to run an entire suite of dozens of tests. » Mean that you can focus on getting your logic to work before you figure out how to make the results look good.
to maintain state in the setUp or tearDown methods of your tests. » Make sure you're always testing on a clean database. NSPersistentStoreCoordinator's NSInMemoryStoreType is your friend. » When using asynchronous methods, whether with delegates or blocks, XCTestExpectation is your friend in Xcode 6.
want to centralize, but for which a subclass seems a bit too specific. » Makes it easy to combine various pieces of added functionality without having a crazy nest of subclasses. » Add functionality not just to one class, but to all of its subclasses.
subclass of UIView into a circle. In Objective-C: UIView+XYZApp: - (void)xyz_circleify { self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2; self.clipsToBounds = YES; } would be available anywhere you #import UIView +XYZApp.h.
layer.cornerRadius = CGRectGetWidth(frame) / 2 clipsToBounds = true } } Since Swift doesn't require importing, this is available anywhere in your module.
prefix your category methods with a three letter prefix and an underscore like xyz_circleify » This prevents your method from colliding with one of Apple's if they ever decide to add their own circleify method » Also makes it easy to pick out which methods you wrote vs. the ones created by Apple at a glance.
» Restart Xcode, » Do the hokey pokey and turn yourself about. » Uninstall by hunting down obscure folder and then forgetting what the hell you were doing in there.
comments » XToDo - To-Do list from your //TODOs » BBFullIssueNavigator - see the whole issue » FuzzyAutocomplete - Way better autocomplete » SCXcodeMiniMap - A Sublime-Text style overview in the left gutter of your code view.
dozens and dozens of open- source UI controls. » If you've got a vague idea of what you want to do, this can help you narrow down what works and what doesn't from a conceptual standpoint » Don't reinvent the wheel if you don't have to » If you do have to, get an idea of where to start
not » As you look through controls, you can start to spot patterns of what controls are easy to design and implement, and which ones take monstrous amounts of work. » Evaluate which path will actually cause you less grief: Adding yet another dependency, or rewriting something yourself and being able to customize it exactly to your needs.
through and creates private files (which are continually regenerated whenever you change your model) and public subclass files (which you can edit) make it easier to change your Core Data model during development. » No more NSManagedObject+Human.h categories to add additional functionality to your NSManagedObjects!
all the boilerplate code you'll need for accessing values like normal properties instead of constantly using valueForKey. » Creates structs which point to strings representing all values and relationships on a managed object, so you don't have to use stringly- typed code to create NSPredicates or NSSortDescriptors:
Structs. » In Swift, a struct is any non-object data structure, and it is always passed by value. » Structs are cheaper to create than Objects, but cannot take advantage of Automatic Reference Counting. » NSRange, CGRect, and CGSize are some examples of Apple-provided structs.
to be marked with __unsafe_unretained so they'll compile using ARC. » Since ARC can't really see into structs, putting something in a struct implies that you will handle its memory management. » If you're declaring const structs, you don't actually need to worry about memory management since they're constant and will never get deallocated.
common in Swift. Anything which does not require inheritance is defined as a Struct - including String. » You can create your own structs similarly, but without the noise of having to declare members __unsafe_unretained struct HUMUserDefaultKeys { let hasRunBefore = "__kHasRunBefore" let hasPermissionForUsageStatistics = "__kHasPermissionForUsageStatistics" } var before = HUMUserDefaultKeys().hasRunBefore
Unlike Apple's built-in UI testing tools, which use JavaScript, you can write KIF tests in Obj-C or Swift (thought Swift requires extra setup). » Uses accessibility labels to drill through the view hierarchy and find the view you want to tap or inspect. » A great way to justify adding accessibility to your app to bean-counters.
user interface - remember that you should try to keep these tests focused on your user interface and information flow, NOT whether your server is working. » Be aware that if your app uses CoreData or has complex animations, you may occasionally need to add some [tester waitForTimeInterval:] calls to allow saves or animations to complete before moving to the next step.
since they will be read out loud to your visually impaired users. » Running a suite of KIF tests takes longer than standard unit tests (minutes vs. seconds), since it's tapping through your user interface. » Sometimes, KIFTypist can get ahead of itself. This has gotten better recently, but when a test fails, check to make sure the right string was input.
before doing this. » Having translated a couple apps for both iOS and Android, the biggest thing I prefer on Android is string resource management. » All user-facing strings are kept in a single file per language, and are given unique IDs. » mTextView.setText(R.string.my_string_name) will set a string with the ID my_string_name from a resources file, which will be accessed by language.
into action in an iOS-friendly way » My solution: An NSString+AppName category with all of the user-facing strings in the application: + (NSString *)xyz_continue { return NSLocalizedString(@"Continue", @"Continue text"); } » Centralizes and makes it possible to organize localized strings, helps prevent duplicate keys and duplicate values, and makes strings auto- completeable.
has made something you need to do over and over again harder than it needs to be. » When nobody else has already written a library for this task. » When taking the time to write the library will save you time in the end.
lot of problems with accessing multiple dimensions of image without having to use multiple strings to access the images. » You still have to call the image using a string: [UIImage imageNamed:@"AnImage"] » Did I mention that I hate stringly-typed code? » KSImageNamed Xcode plugin gave you auto-complete on strings, but still left strings scattered all over the code.
and spits out a category on UIImage with the names of every image as a method so instead of writing: [UIImage imageNamed:@"My Image Name"]; you can write: [UIImage ac_My_Image_Name];
image calls » Auto-complete on method names » Can be easily run with a script any time you update your code (or even every time you build your code) » The script rewrites the file every time it runs, so any image called programmatically is guaranteed to be there. » Throws obvious errors when you remove an image.
images at compile time instead of runtime. » Auto-complete, especially with FuzzyAutocomplete is way faster than trying to remember how to spell something. » By taking the time to write and test a library, I have something I know will work every time, without having to re-test it.
About a month after Cat2Cat went public, Square released objc codegenutils: » objc-assetgen does the same thing as Cat2Cat. » objc-colordump outputs a file of UIColors from your Interace Builder color palette. » objc-identifierconstants dumps segue identifiers and VC identifiers out into files or each
read, and keep it separated by purpose, so it's easy to fix. » Get rid of stringly-typed code so it's harder to break in the first place. » Use the tools other people have built to enhance your laziness, or build new tools yourself. » Best practices are secretly the lazy way to code.