Prerequisites
To properly follow this material, you must have the following in place:
1. You must have Xcode (7.2 or higher version) installed on your Mac OS X.
2. You must have the iOS simulator running.
Running the iOS simulator
The iOS simulator is integrated with the Xcode IDE, but can also be used separately. To start the simulator, open the command line/terminal and run the following command:
$ open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app
The iOS application bundle structure
Before we start creating our app, we must first understand the anatomy of an iOS application bundle. A typical iOS application bundle contains the application executable and any resources used by the application. Here is a structure of a typical simple iPhone application (in executable format) called MyApp.
MyApp.app/
MyApp
Info.plist
AppIcon.png
MyApp - (Required) This is the executable file containing the application's code. The name of this file is the same as the application (directory) name, minus the .app extension.
Info.plist - (Required) The Information property list file contains configuration information for the application, such as its bundle ID, version number, display name, etc.
AppIcon.png - (Recommended) Application icon is used to represent the application in the home screen.
Procedure for developing and compiling an iOS app
Here is an overall procedure for creating an iOS application from scatch, then compiling the application and executing it on the iOS simulator:
1. Write the source code (.h and .m files)
2. Compile the source code file/s (.m) and link the results to an executable binary
3. Generate the Info.plist file
4. Add an application icon
5. Install the resulting files to the simulator
6. Execute the app in the simulator
For the purpose this tutorial, we will create an iOS app that has a custom view that triggers an animation when the view is clicked. We will proceed by going through the above-described procedure, one step at a time.
1. Write the source code
The execution of every C program starts with a function called main(), and since Objective-C is a superset of C, the same is also true for an Objective-C program. We can write our source code using any text editor. Each of the following will go in a separate file.
main.m
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
AppDelegate.h
#import "ViewController.h"
@interface AppDelegate : NSObject <UIApplicationDelegate>
@property (nonatomic) UIWindow *window;
@end
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opts {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[ViewController alloc] init];
return YES;
}
@end
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController
@end
ViewController.m
#import "ViewController.h"
@implementation ViewController
-(void)loadView {
CustomView *customView = [[CustomView alloc] init];
[self setView:customView];
}
@end
CustomView.h
#import <UIKit/UIKit.h>
@interface CustomView : UIView
@end
CustomView.m
#import "CustomView.h"
@implementation CustomView
{
UIButton* button;
int width;
int height;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:@"Click me!" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor whiteColor]];
[self addSubview:button];
[button addTarget:self action:@selector(onButtonClick:) forControlEvents:UIControlEventTouchDown];
}
return self;
}
-(void)onButtonClick:(UIEvent*)event {
[UIView animateWithDuration:1.0 animations:^{
int py = button.frame.origin.y;
if(py == 0) {
button.frame = CGRectMake(0, height, width, height);
[button setBackgroundColor:[UIColor yellowColor]];
}
else if(py == height) {
button.frame = CGRectMake(0, 0, width, height);
[button setBackgroundColor:[UIColor greenColor]];
}
}];
}
- (void)drawRect:(CGRect)rect {
width = self.bounds.size.width;
height = self.bounds.size.height / 2;
button.frame = CGRectMake(0, 0, width, height);
}
@end
2. Compile and link the code
Open the command line/terminal and cd to the directory where your .h and .m files are located. Then run the following commands:
$ XCODE=/Applications/Xcode.app/Contents/Developer
$ $XCODE/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang \
-x objective-c \
-arch i386 \
-std=gnu99 \
-fobjc-arc \
-isysroot $XCODE/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk \
-fobjc-abi-version=2 \
-mios-simulator-version-min=6.0 \
-Xlinker -objc_abi_version -Xlinker 2 \
-fobjc-link-runtime \
-framework CoreGraphics -framework UIKit -framework Foundation \
*.m -o MyApp
NOTE: If you encounter errors saying that "UIKit/UIKit.h" is not found, this may be due to a different (or particular) version of the iPhone simulator SDK. Look into the contents of the directory "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/" and adjust the -isysroot parameter in your command accordingly to resolve this.
Check the executable file:
$ file MyApp
It should display something like this:
MyApp: Mach-O executable i386
3. Generate the Info.plist file
This contains the configuration information for the application. Save this file in the same directory with the compiler MyApp file, created above.
Info.plist
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>MyApp</string>
<key>CFBundleExecutable</key>
<string>MyApp</string>
<key>CFBundleIconFiles</key>
<string>AppIcon</string>
<key>CFBundleIdentifier</key>
<string>xxx.sample</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
4. Add an application icon
Add any image (PNG) to your working directory and rename it to "AppIcon.png". Apple recommends that you always create the icon files using the PNG format. The filename of the image without .png extension will be the value for the CFBundleIconFiles in the "Info.plist" file.
5. Install the resulting files to the simulator
First, we need to create a directory MyApp.app/.
$ mkdir MyApp.app
Then, copy the output file "MyApp", "Info.plist" and "AppIcon.png" to the directory MyApp.app/.
$ cp MyApp MyApp.app/
$ cp Info.plist MyApp.app/
$ cp AppIcon.png MyApp.app/
Finally, install the app to simulator:
$ xcrun simctl install booted MyApp.app
When this command completes, your application has been installed to the running iOS simulator (this is why we will need to execute the simulator first).
6. Execute the app in the simulator
Go the your iOS simulator windows and run "MyApp" from the application menu.
Additional Info
Aside from the executable file (MyApp), the information property list file (Info.plist), and the application icon (AppIcon.png), your bundles may (and often will) also include other types of files. Here are the contents of a typical iOS application bundle.
MyApp.app/
MyApp
Info.plist
AppIcon.png
SearchIcon.png
Default.png
Settings.bundle
SettingsIcon.png
en.lproj/
MyImage.png
fr.lproj/
MyImage.png
*Icon.png - (Recommended) Application icons are used at specific times to represent the application. For example, different sizes of the application icon are displayed in the home screen, in search results, and in the settings application. Not all icons are required but most are recommended.
Default.png - (Recommended) One or more images that show the initial interface of your application in a specific orientation. The system uses one of the provided launch images as a temporary background until your application loads its window and user interface. If your application does not provide any launch images, a black background is displayed while the application launches.
Settings.bundle - The Settings bundle is a special type of plug-in that contains any application-specific preferences that you want to add to the Settings application. This bundle contains property lists and other resource files to configure and display your preferences.
*.lproj - Custom resource files. Non-localized resources are placed at the top level directory and localized resources are placed in language-specific subdirectories of the application bundle. Resources consist of images, sound files, configuration files, strings files, and any other custom data files you need for your application.
Your own bundles would include some or all of the resource files depending on the features you support.