Life is good
SDK and Deployment Target
I see that my answer to the question What’s the meaning of Base SDK, iOS deployment target, Target, and Project in xcode gets lots of views, so I think I need to elaborate more about it
Good read
- iOS 7 TechTalk - Architecting Modern Apps, Part 2
- Configuring a Project for SDK-Based Development
Base SDK
- We can’t configure this anymore, as Xcode will use the latest SDK. For Xcode 7, the SDK is iOS 9
- If we upgrade Xcode, it will use the newer version of the SDK. Like Xcode 7.2, the SDK is iOS 9.1
-
Choosing the latest SDK for your project lets you use the new APIs introduced in the OS update that corresponds to that SDK. When new functionality is added as part of a system update, the system update itself does not typically contain updated header files reflecting the change. The SDKs, however, do contain updated header files.
Deployment Target
- We can set in Xcode -> Target -> Deployment Info -> Deployment Target
- State that we support this iOS version
What does it mean
So, a modern App might use iOS 9 as the Target SDK, and iOS 7 as the deployment target. This means that you can run on iOS 7, iOS 8 and iOS 9, and that you have available to you any iOS 9 calls when actually running on iOS 9.
.
Each .sdk directory resembles the directory hierarchy of the operating system release it represents: It has usr, System, and Developer directories at its top level. OS X .sdk directories also contain a Library directory. Each of these directories in turn contains subdirectories with the headers and libraries that are present in the corresponding version of the operating system with Xcode installed.
.
The libraries in an iOS or OS X SDK are stubs for linking only; they do not contain executable code but just the exported symbols. SDK support works only with native build targets.
So the SDK is just like stub and header only. It means that we can use certain APIs, but on OS that does not have the real symbols for those APIs, it crashes
available
Swift 2 introduces available
construct that guards against failure when trying to use newer APIs.
Note that available
is runtime, not compile time. All the code is inside your executable
1 |
if #available(iOS 9, OSX 10.10, *) { |
deprecated APIs
Always check to see if you are using deprecated APIs; though still available, deprecated APIs are not guaranteed to be available in the future
Compile time vs Runtime
1 |
#if (arch(i386) || arch(x86_64)) && os(iOS) |
1 |
#if os(OSX) |
1 |
// All the code gets inserted into executable, but is run depending on the version of the OS |
Weakly vs strongly linked
- Weak Linking and Apple Frameworks
- What does it mean to “weak-link” a framework?
- Frameworks and Weak Linking
For example, suppose in Xcode you set the deployment target (minimum required version) to “OS X v10.5” and the base SDK (maximum allowed version) to “OS X v10.6”. During compilation, the compiler would weakly link interfaces that were introduced in OS X v10.6 while strongly linking interfaces defined in earlier versions of the OS. This would allow your application to run in OS X v10.5 and take advantage of newer features when available.
.
None of the (platform) frameworks is really “included in the bundle”. Instead, your app has a reference (“link”) to a framework once you add it to the “Link Binary with Library” build phase. The frameworks are pre-installed on the devices. When you run an app, all the app’s framework references are resolved by the dynamic linker (on the device), which means the framework code is loaded so your app can use it.
Reference
NSApplicationDelegate and notification
In an iOS project, we often see this in AppDelegate
1 |
|
But in a Cocoa project, we see this instead
1 |
|
In this case the param is of type NSNotification
Delegate and notification
Reading Cocoa Core Competencies - Delegation
The delegate of most Cocoa framework classes is automatically registered as an observer of notifications posted by the delegating object. The delegate need only implement a notification method declared by the framework class to receive a particular notification message. Following the example above, a window object posts an NSWindowWillCloseNotification to observers but sends a windowShouldClose: message to its delegate.
So the pattern is that the delegate should strip the NS
and Notification
, like NSWindowWillCloseNotification
to windowShouldClose:
Digit grouping in Swift
When working on Scale I think it’s good to have a way to group the digit so that it is easier to reason
Luckily, Swift already supports this. See The Swift Programming Language - Numeric Literals
Numeric literals can contain extra formatting to make them easier to read. Both integers and floats can be padded with extra zeros and can contain underscores to help with readability. Neither type of formatting affects the underlying value of the literal
1 |
let paddedDouble = 000123.456 |
Talking about grouping digits after the decimal point, it is interesting too Convention of digit grouping after decimal point
So now we have
1 |
public enum MetricUnit: Double { |
Selecting objects in Xcode Interface Builder
There are some ways to select objects in Xcode Interface Builder
- Document Outline
- Jump Bar
- Shift + Right Click
iOS best practices
Here are practices I found useful when developing iOS.
They can be tools or framework that greatly affect your style. Sometimes, it applies to other platform as well
Architecture
We’re always looking for ways to structure our apps better, I collect some cool stuffs in ios-architecture
Name it right
- Name It Right
- Cocoa style for Objective C
- swift-style-guide
- swift-style-guide
Naming is hard. But we can start by naming correctly and with correct spelling. The best way is to stick with the platform naming convention
Project structure
Some prefer to group their projects by object role, like Model, View, View Controller. But I prefer to group by feature or use case, learning from Clean Architecture
- When you look at a software system, and all you see is MCV in a web configuration, then the architecture of that system is hiding the use cases of that system and exposing the delivery mechanism.
I often group my code like this
- Share: Contains code that can be useful to other project. Not related to any project. Can be extract to a Pod
- Engine: Contains code that is specific to this project. Like UserManager, ViewAnimator, …
- Modules: Separate each screen into module. In each module, there are view, view model and wireframe
There are some architectures like MVC, MVVM, VIPER, VIP, … and you may want to leverage some templates to help creating projects faster, like
And learn how to make them
- Custom Xcode File Templates
There are also some scripts to bootstrap your project
- crafter Crafter - Xcode project configuration CLI made easy
- xcake Create your Xcode projects automatically using a stupid simple DSL.
- liftoff CLI for creating and configuring new Xcode projects
Functional Reactive Programming
The Reactive Extension inspired libraries are cool, and they greatly changes the way you develop, especially signal chaining
Unidirectional data flow
Another trend is React inspired libraries, which encourage Unidirectional data flow
Data manipulation
Leverage some functional style for better data manipulation
- Swiftz It defines functional data structures, functions, idioms, and extensions that augment the Swift standard library.
- Dollar.swift A functional tool-belt for Swift Language similar to Lo-Dash or Underscore.js in Javascript
Prefer decoration over extension
This maybe subjective. But in some case decoration wins
Often when we want to add custom color, font or animate a view, or custom NSDateFormatter
, we often make categories on UIColor, UIFont, UIView, NSDateFormatter
, …
But most of the case, we can group them inside class, like ColorBucket, FontBucket, ViewAnimator, DateFormatterBucket
, …
So, instead of
1 |
@interface UIColor (Additions) |
We can have ColorBucket
1 |
@interface ColorBucket |
Mixin
- Mixins and Traits in Swift 2.0
Another way to add functionality to an entity is mixin, which is cool
IoC container
Usage of IoC container can greatly change the app workflow, which praises Dependency Injection
Single Responsibility Principle
Always keep this in mind :]
Performance
Understanding of performance issue, especially some common uses like tableview pre rendering, helps
- Easy UITableView optimizations
- 25 iOS App Performance Tips & Tricks
- iOS Quick Tip: 5 Tips to Increase App Performance
- Mastering UIKit performance
Main thread
It’s good to care about our main thread so see if it is blocked
- PSPDFUIKitMainThreadGuard.m This is a guard that tracks down UIKit access on threads other than main
- Watchdog Class for logging excessive blocking on the main thread
Overlay app icon with build information
Show TODO FIXME as warnings
- HOW TO HIGHLIGHT YOUR TODOS, FIXMES, & ERRORS IN XCODE
-
XToDo Xcode plugin to collect and list the
TODO
,FIXME
,???
,!!!!
Use this script in Run Script Build Phase
1 |
KEYWORDS="TODO:|VERIFY:|FIXME:|\?\?\?:|\!\!\!:" |
Breakpoints
There are some common needed breakpoints, like Breakpoints_v2.xcbkptlist
Code snippets
Code snippets auto generate common code
Utility class
We can avoid duplicated helper classes in projects by using some cool frameworks
- Sugar Sugar is a sweetener for your Cocoa implementations.
Xcode plugins
Using Xcode plugins can boost your productivity
And learning to write your own can assist you with more tasks
Xcode keyboard shortcuts
Navigate faster
xcconfig
Build yourself some predefined xcconfig
- Using xcconfig files for your XCode Project
- Warnings-xcconfig An xcconfig (Xcode configuration) file for easily turning on a boatload of warnings in your project or its targets.
- XcodeWarnings xcconfig to enable lots of Xcode warnings
Strongly typed resource
There’s some scripts that generate strongly typed resource classes
- SwiftGen A collection of Swift tools to generate Swift code (enums for your assets, storyboards, Localizable.strings, …)
- R.swift Get strong typed, autocompleted resources like images, fonts and segues in Swift projects
Continuous learning
Technologies move really fast. We must learn continuously. I have ios-resources to keep track of all the cool stuffs
Also, I leverage Github as my notes ios-issues
Reference
Symbolic breakpoints in Xcode
Symbolic breakpoints are breakpoints based on symbols like functions or methods.
In Swift
You can set symbolic breakpoints on any free functions, instance and class methods, whether in your own classes or not.
Here is an example
1 |
func freeFunction() { |
You can have some breakpoints in Swift like
1 |
UIViewController.viewDidLoad |
- There seems no difference between instance and class methods !!
-
Robot.MyStruct.staticMethod
says that it must matchstaticMethod
inside Robot.MyStruct - With
instanceMethodWithArguments
, Xcode Breakpoint panel shows options for(Robot)(Swift.Int)(b: Swift.Int) -> Swift.Int
and(Robot)(Swift.Int)(b: Swift.Int)(c: Swift.Int) -> Swift.Int
. This may remind you of Instance Methods are Curried Functions in Swift - I thought that symbolic breakpoint must match
Selector
, likeinstanceMethodWithArguments:b:c
, but it is not - Objective-C style
-[UIViewController viewDidLoad]
or-[Robot instanceMethod]
does not work !!
And talking about Swift selector, you may want to take a look at this proposal Referencing the Objective-C selector of a method
In Objective-C
1 |
void freeFunction() { |
You can have some breakpoints in Objective-C like
1 |
-[UIViewController viewDidLoad] |
- We must specify the correct method with arguments like
-[Robot instanceMethod:b:]
- I use another Swift class into this Objective-C project
1 |
public class Animal: NSObject { |
but the symbolic breakpoint -[Animal hello]
does not work. Only Animal.hello
works !!
Syntax
- There are Swift syntax
Animal.hello
and Objective-C syntax-[Animal hello]
. It seems that Swift syntax must be used on Swift files. So in Swift project, we should use Swift syntax -
init
is instance method, see How to swizzle init in Swift
System symbols
Symbolic breakpoints are helpful in case you want to inspect system behaviours
Auto Layout
Breakpoints_v2.xcbkptlist
- Breakpoints_v2.xcbkptlist A list of common symbolic breakpoints and actions
swift_willThrow
- Breakpoint on all throws
objc_exception_throw
It is your Exception Breakpoint
with Break
set to Throw
There’s a Break
type Catch
also
Swizzle
Symbolic breakpoints help when you want to understand system call, like when you try to make Xcode plugin
See How To Create an Xcode Plugin: Part 1/3 on how to break in initWithIcon:message:parentWindow:duration
Assembly
Break on system classes and you want to understand the parameters there, so an understanding of assembly helps
- How to get parameters using symbolic breakpoints in Objective-C
- A Whirlwind Detour of Assembly
- Disassembling the Assembly, Part 1
- iOS Assembly Tutorial: Understanding ARM
Interesting
Some interesting questions
chisel
Facebook has chisel, which is a collection of lldb commands in Python
Specifically, bmessage
Set a symbolic breakpoint on the method of a class or the method of an instance without worrying which class in the hierarchy actually implements the method.
Reference
Some Mac OSX Tools
Mac OS X has some useful tools that you may overlook. They are useful in your daily development
Network Link Conditioner
Simulate network condition. Accessible from System Preferences -> Network Link Conditioner
ColorSync Utility
Pick and convert color. Accessible from Applications/Utilities/ColorSync Utility.app
Automator
Write script to automate task. Accessible from Applications/Automator.app
libdispatch aka GCD in iOS
App backed by website in iOS 9
iOS 9 introduces new ways for your app to work better, backed by your websites
Smart App Banners
If the app is already installed on a user’s device, the banner intelligently changes its action, and tapping the banner will simply open the app. If the user doesn’t have your app on his device, tapping on the banner will take him to the app’s entry in the App Store
To add a Smart App Banner to your website, include the following meta tag in the head of each page where you’d like the banner to appear:
1 |
|
Universal Links
When you support universal links, iOS 9 users can tap a link to your website and get seamlessly redirected to your installed app without going through Safari. If your app isn’t installed, tapping a link to your website opens your website in Safari.
Web Markup
If some or all of your app’s content is also available on your website, you can use web markup to give users access to your content in search results. Using web markup lets the Applebot web crawler index your content in Apple’s server-side index, which makes it available to all iOS users in Spotlight and Safari search results.
Shared Web Credentials
Shared web credentials is a programming interface that enables native iOS apps to share credentials with their website counterparts. For example, a user may log in to a website in Safari, entering a user name and password, and save those credentials using the iCloud Keychain. Later, the user may run a native app from the same developer, and instead of the app requiring the user to reenter a user name and password, shared web credentials gives it access to the credentials that were entered earlier in Safari.