Professional Documents
Culture Documents
Table of Contents
1 4 7 13 17 22 27 The iOS Revolution Step 1: Dene Your App Step 2: Design Your App Step 3: The iOS Architecture Step 4: What is Xcode? Step 5: Hello World Sample App Step 6: Sample App with a Backend
running at $333 million a rate of about $4 billion per year remarkable for a store that only opened in July 2008. Another innovation that has spurred iOS app development is The Cloud. Cloud services make it easier for independent developers to create, support and make money from their apps. The Cloud solves data storage and cross-device and user-to-user sharing problems. If an app stores data in the Cloud, that part of the application is called the backend, while the part of the app that runs on the phone and interacts with the user is called the front end. A cloud may be private i.e., the services belong to an organization for the benet of its employees and business partners. Or a cloud may be public i.e., a company (such as Amazon or Kinvey) owns the services, which developers can then integrate into their own apps. If you are a developer and want to build your own backend, you certainly can do that. Whether you want to or not depends on whether your backend provides functionality common to many dierent apps. If it does (as in a shopping cart or user authentication) then perhaps that time and money would be better spent on features that oer unique value to your customer. You may be better o hooking into a commercial backend provider via an API. Then you can focus on what counts most a unique user experience and application-specic functionality. That brings us to the rst step in making an app.
must-have core capabilities include: Performance (e.g., fast screen refresh) Oine capability (i.e., ability to work when not connected to the Internet) Location awareness (e.g., the data/experience will change with the users location) Cloud syncing (e.g., users see the same data on multiple devices) Push notications (i.e., sending updated information to devices as soon as it is available) When you have a handle on what your app does, the next step is to design it. Designing your app involves making choices of how information and controls are presented to the user as well as how to implement app logic, and guring out what data lives locally and what belongs in the Cloud.
Your apps features will inform its architecture, which is how youll divide the code and data into functional parts. If your app requires interacting with other app users or networked services, youll need to gure out what piece of the logic lives in the app code and what comes from the backend. For example, your app might integrate with a restaurant recommendation engine, share user location, or pull real-time trac data. This is done using APIs provided by various service providers but you dont have to wire up your app to a network to get started. You can develop a prototype using predened representative (or dummy) data. Its easier to ne-tune the front end if you dont have to simultaneously modify your backend too. Once you get the apps look-and-feel right, then make those backend connections.
inform its architecture, which is how youll divide the code and data into functional parts.
Once youve got the overall concept for your app, the next step is to express that design in terms of the iOS app architecture. That architecture is the model for what parts an iOS app can contain and how those parts t together. Its a well thought-out approach for translating a product concept into actual code you can deploy on a device.
WHY iOS? Besides the features and design of your rst app, theres one more decision you need to make before you start actual development. Thats whether to deploy on Apples iOS platform or on Googles Android platform. (Some of this is also covered in our ebook, How to Make an App: Android Edition.) Reasons to develop for iOS include:
Why iOS?
$ $$
Customers more willing to pay The Apple ecosystem
{-X-}
All-in-one IDE The Apple experience Tablets
Customers more willing to pay. Perhaps its because of Androids open source heritage, but whatever the reason, Android apps generate less than 10% of the total dollars spent on mobile apps, despite having 75% of the smartphone market itself and despite the fact that the average selling price of an app in the Google Play is $3.79 versus Apple App Stores $2.01. In other words, Apple users are much more willing to spend money on apps. The Apple Ecosystem. Some developers and users prefer Apples closed and more tightly controlled environment. Apples ecosystem, consisting of Xcode, iCloud, iTunes, the App Store, the iPad, the iPhone, Mac computers, etc., oers a very holistic user experience with the ability to share data seamlessly across devices plus the
10
assurance of having applications pre-approved for quality and content prior to going on sale. Xcode. Apples all-in-one IDE oers state-of-the-art oers features like a graphical interface builder and a syntax-aware and compiler-aware source editor. The Apple Experience. From the t and nish of its hardware to the customer service in its retail stores, to the way its hardware and software work awlessly together, Apple has created the premium brand in consumer electronics. iOS developers share the benets so when someone downloads your iOS app, they already expect its a great product. And that it will also work awlessly on their device. Tablets. iOS has a clear advantage over Android in terms of tablet market adoption. Using Xcode, its also much easier to migrate an app from a phone to a tablet and vice versa than it is when developing for Android. Why Not iOS? Although iOS oers many compelling advantages as a platform for your mobile app, it also comes with some disadvantages. Here are three:
Closed platform
Market growth
Approvals
Closed Platform. iOS apps only run on Apple products so you cant take advantage of features (like NFC) available only on non-iOS devices or market growth of non-iOS devices.
11
Market Growth. Today, iOS represents less than 15% of the total smartphone market, Although the total market (the whole pie) is still increasing at a fast rate, Android market growth outpaces iOS growth. Approvals. The App Stores app approval process is notoriously more time consuming than Google Plays process.
Of the over 700,000 iOS apps available in the App Store, 250,000 of them are specifically for iPad. Whether you develop for iPhone or iPad depends on a number of factors, including: Screen Size. Most people do not want to watch a movie or read a book on a smartphone, so if your app is better suited for a larger screen, you should consider iPad. Portability. On the other hand, if your app is something people are likely to use when they are out and about, such as when shopping, then iPhone may be your primary target. Media. Because it is more portable, iPhone is a better device for taking pictures and video while iPad offers a better viewing and editing experience (again, because of screen size). Consuming or Creating? As in the editing case, if your app is more about working with content than consuming it, you probably are better off developing for iPad.
12
14
15
(produced in a model). This is where developers spend most of their time constructing the View Controller by dening and attaching actions (or behaviors) to onscreen widgets. When the user taps a button, for example, it is the View Controller that determines what action will occur, such as retrieve stored data from your Kinvey-based data store. The link between a view object (like a button) to a controller action is called a connection. Frameworks. You dont actually have to write most of an apps logic. It already exists as frameworks. A framework is a collection of classes that implements some function such as connecting to the Internet, drawing a button, etc. Rather than write the code from scratch, you just use the frameworks supplied by iOS. Some frameworks are automatically present when you start a new project while others may need to be added (done via a drop down menu in Xcodes Project Editor). Delegation. Say, you want to customize the behavior of a frameworks object. You cant actually modify the code of the framework class itself (prohibited since other apps may also use the framework). But what you can do is provide app-specic behavior in an application delegate object. If a delegate implements a method, it will be called by the delegating class to modify its behavior. In the Kinvey sample app (one of two examples we will be describing below), the AppDelegate.h and AppDelegate.m the header and implementation les for the UIApplicationDelegate, respectively contain the code that authenticates an app to the Kinvey backend service. Storyboards and XIBs. The MainStoryboard.storyboard le (or a .xib le, if you did not click on the Use Storyboard option when starting your project) contains the view information needed to implement the overall ow and display of your application and the user interface elements. Windows. Each view (e.g., the contact list and individual contact details in the Contacts app) exists within a window. The window represents the entire device screen and is where all your views are presented.
16
Outlets. A variable by which a view object can be referenced in a controller. (For example, if you place a text eld to capture a user's name, you might create an outlet called UITextField* nameField.)
Supporting les. These are les that provide resources (like PNG images and other static data) that your app needs as well as les that congure how the app will run. Other examples: .pch les precompiled headers used for the code les in your project. .plist les property lists that are small amounts of persistent data (like your apps default user settings) consisting primarily of strings and numbers that you want your app to be able to access, modify if needed, and write back into the property list. main.m le your apps main function. This is needed to launch the app, but you will not need to modify this le. InfoPlist.strings le used for localization. Products. This is the le for your app (i.e., YourProduct.app) that is built when you click Xcodes run button. Making an iOS app involves working with these features in the typical, straightforward workow: Storyboard your views by dragging and conguring graphical objects on a template Adding behaviors to the various widgets Writing the classes as to dene those behaviors (including delegates) Adding needed support les Building and running the app Iterating until you are satised with your app This is all done within Xcode.
5 Whats Xcode?
18
Whats Xcode?
You can start developing functional, good-looking apps almost from the moment you download Xcode, Apples integrated development environment (IDE) for making iOS and Macintosh apps. Among other features, Xcode includes a source code editor, graphical user interface (GUI) editor (sometimes called Interface Builder), source code repository manager, compiler, and much more. iOS applications are typically developed by manipulating views graphically and by typing Objective-C code for the models and controllers. To get Xcode, simply go to the App Store and download the application (its free). To do this, click on the App Store icon in your Macs dock, or visit https://itunes.apple.com/us/genre/ios/id36?mt=8 The app store will download and install Xcode in your Application folder. From Applications, double-click the Xcode icon to launch Xcode and youll see its splash screen (Figure 1). From there you can click on Create a new Xcode project to take you to a menu of several templates on which to base your application. Selecting a template opens an Xcode workspace pre-populated with frameworks and other les Xcode thinks you will need using that template.
19
Although you can develop, build and simulate your app on your computer in Xcode, you cant run your app on a target device (even your own iPhone) until you become a registered iOS developer and join the iOS Developer Program. To do that, go to developer.app.com/ and navigate to the iOS Dev Center. While there, you will also nd documentation, sample code and other useful resources such as information on how to submit your app to the iOS App Store.
Everything you do in Xcode is done in a window, called a workspace (Figure 2), consisting of multiple work areas, some of which are also divided into panes. All the les needed to build your app belong to a project, and the Navigator area (far left) lists all your projects (there can be several in a workspace) and all les for each project. Clicking on a le in the Navigator area shows its contents in the Editor area and invokes the appropriate editor. Clicking on a .h or .m le, for example, shows the les source code and invokes the Source editor, so you can edit the code. Clicking on .storyboard or .xib (sometimes called a nib) le shows the apps storyboard and invokes the Interface Builder, so you can design a view using the Builders drag and drop features. An especially handy feature is that the Editor area can have both a right and a left pane with each pane aware of your edits in the other. So, for example, you can simultaneously edit an objects .h
20
header le in the left pane and its corresponding .m in the right pane. Or you might click on a button object (displayed graphically) in the left pane and edit its methods source code in the right pane. To toggle between a single pane (the Standard Editor) and double pane view (the Assistant Editor), use the Editor selector button on the right of the toolbar. You can option+command+click a symbol in the editor to open the denition in the opposite editor pane. You can also resize the entire Editor area simply by dragging its borders. For even more editing space, you can also remove the Debug area or both the Debug and Utility areas using the View Selector button on the far right of the toolbar. As its name suggests, the Debug area shows information, like variable state and console logs, helpful in debugging code. The Utility area has two panes: the Inspector and Quick Help pane (top) and the Library pane (bottom). Although there are ve inspectors File, Help, Identity, Attributes, Size and Connections only the inspectors that are currently relevant appear in the Inspector list at the top of the pane. (To see the name of an inspector, move the cursor over its icon in the Inspector selector bar.)
your app on a target device until you become a registered iOS developer...
You will use inspectors to add and modify object attributes for views in the Interface Builder. For example, if you click on a UILabel in the Editor area of a storyboard, you can use the Attributes inspector to change the labels color and use the Size inspector to change the labels size. The Help inspector shows help information about a selected class. Use the Identity inspector to view and manage an objects metadata such as its class, runtime attributes, label and so forth. Use the
21
Connections inspector to view the outlets and actions of an interface object, to make new connections and to delete existing connections. The Library pane has libraries of resources (like le templates, code snippets, interface objects and media les) that are prebuilt and ready to insert into your project. Use the Library selector to select which of these libraries (e.g., code snippets or interface objects) you wish to insert. To insert one, drag it directly into your storyboard while using the Interface Builder editor. These are basics you need to know to get started using Xcode to build your rst app. But to really understand how its done, it helps to walk through an actual app or two. Lets start with a simple Hello World app that does not employ a backend connection, and then look at a somewhat more functional app that does.
23
To get started, launch Xcode and select Create a New Xcode Project. From the iOS Application templates, select Single View Application and click Next. Fill in your products name and a company identier, typically com.yourCompanyName. Deselect Use Storyboards and leave Use Automatic Reference Counting selected. Then click Next and select a destination for your projects les.
24 1
Follow these steps to make your app: 1. Select your projects ViewController.xib le in the Navigator (Figure 4), to open the Interface Builder editor. 2. Drag a Round Rect Button from the Objects library (lower right) onto the view in the Editor area; select the buttons text and type Press Me. 3. Drag a Label from the objects library onto the view, as well. 4. Select and drag the Label sizing handles, centering the object and making it wide enough to hold the Hello World! text; then,
5. With the Hello World! label still selected, click on center alignment in the Attributes inspector. 6. Open the Assistant Editor (Figure 5), exposing the source code header le (ViewController.h) of the view controller you just built graphically. 7. Select the button and control-drag from the button to just below the ViewController denition in the Assistant panel. In the form that opens, select Action for the connection type, type in a name (showText) and click Connect. This creates an interface builder (IB) action as highlighted in Figure 6.
25
8. Next step is to create an outlet for the label. To do this, select the label object and control-drag from the label to just below the IB action you just created. Select Outlet as the connection type and enter a name label and click Connect. This creates an interface builder (IB) outlet as shown in Figure 7.
26
9. Finally, its time to add some logic to the view controller so it knows what to do when the button is pressed. To do this, select ViewController.m in the project navigator to show the code editor. Find the buttons IBAction you just created (near the bottom), place your cursor between the { } brackets and hit the return key a few times to create some extra space. Then in that space type the method for how you want the label you specied to respond: _label.text=Hello World!; as highlighted in Figure 8.
g. 8 _label.text = "Hello World"; will set the label text on the button press.
Congratulations! Your app is done. To build and run your new app in the simulator, click the Xcode Run button in the left corner of the toolbar. When you click the button, the text will update.
28
29
at the very top of the Navigator pane which displays the Project editor and then select the Build Settings tab. For detailed instructions, complete the Getting Started page under Guides on the Kinvey website. But again, you can skip this setup procedure for now in order to run the downloaded Kinvey Test Drive app. But you must still do this step: To run any app that uses Kinvey (including Test Drive) you need to do the Create an App step on the Kinvey website. Click on My Apps in the Kinvey menu bar and then click on Add an App, which will open an Add page. Type in a name for your app and click on the Apple logo and then click Create. The page that opens shows your Apps credentials. Copy and paste the App Key and App Secret into the AppDelegate.m le of the downloaded Test Drive project:
#import "AppDelegate.h" #import <KinveyKit/KinveyKit.h> @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { (void) [[KCSClient sharedClient] initializeKinveyServiceForAppKey:@"<#My App Key#>" withAppSecret:@"<#My App Secret#>" usingOptions:nil]; return YES; }
You are now ready to run the app click on the Xcode run button and wait for the simulator to open and the app to appear (Figure 9).
30
g. 10
g. 11
g. 12
Clicking the + toolbar button opens an alert (Figure 10) with an empty eld into which the user can type some text (e.g., some new data). Clicking save uploads the data to Kinvey and displays text on the screen (a table view) and also displays an alert that the save worked (Figure 11). To test the load function, enter some data (e.g., some data to load) in the name eld of the Kinvey collection. To see the load, the swipe down on the table on the phone until the refresh spinner starts, and then the new data will appear in the table (Figure 12). Figure 13 shows the Kinvey collection after the save that Figure 10 depicts on the iPhone. Figure 14 shows the Kinvey collection after the user adds a new row to the testObjects collection using the web browser. Note that every time a save is done on the iPhone, Kinvey automatically adds a new row (displayed on a collection refresh). To add a new row manually in the browser, click + row, and type some descriptive text in the name column. That data will now load on the iPhone when the user pulls down on the table.
31
Storyboard the Test Drive App Most of the Test Drive user interface objects visible in the simulation are available in Xcodes Object Library and can therefore be added to the view graphically. The UI objects consist of a: Table view Toolbar Tool Bar Button item exible space Tool Bar Button item Add Table view cell Label Title Refresh Control
32
To create this app yourself, you would follow these steps: Launch Xcode and select the Single View Application template Select the Use Storyboard option Replace the default UIviewController object with a UITableViewController Drag and drop the other objects, in the order listed, onto the UIviewcontroller Also note: The Flexible Space Bar Button item lls up the space on the toolbar so the add button is at the right. This is a standard pattern in table-based iPhone apps. The add button shows the system + sign. That is done by dragging a bar button item onto the toolbar, clicking on the Identier drop down menu in the Attributes inspector; and then selecting the Add option. As with the Hello World! app, once your apps view is complete (Figure 15), you would still have to create the various methods and connections that bring them to life. This is done using the Source editor while working with the ViewController.m le.
33
Add View Controller Logic Since the app performs two basic operations (save data to Kinvey and load data from Kinvey) these two methods must be added to the ViewController header le. Thats done with a control-drag from the + bar button over to just under the @interface ViewController line in ViewController.h. (Open the Assistant editor to see both the storyboard and the le source.)
g. 16 Drag an add: action from the button bar to the ViewController header file
During the drag, the popup appears, asking for the name and type of connection. Enter action for the connection type and add for the name. Then repeat the drag, this time from the refresh control and using load for the name (Figure 16). Note: to follow this discussion it will help to have the referenced les open in your Xcode Source editor. In ViewController.m, you will see the implementation code associated with each of the two Interface Builder methods, whose names Xcode added automatically to the .m le: - (IBAction)add:(id)sender - (IBAction)load:(id)sender You will also see a third section of code not associated with these methods, which starts with the line: #pragma mark - Table View Stuff These methods support the table view and are part of UITableViewD-elegate and UITableViewDataSource. They handle controlling the
34
display of the table, and respond to user gestures. For example, swiping a table cell will show the delete button because tableView:canEditRowAtIndexPath: returns YES and tableView:editingStyleForRowAtIndexPath: returns UITableViewCellEditingStyleDelete. If you tap the delete button, the delegate method tableView:commitEditingStyle:forRowAtIndexPath: is called. The code of this method deletes the data for the row and removes it from Kinveys data store. When the backend delete is completed, the app displays an alert describing the success or failure. The way that all three sections (and all Kinvey-enabled apps) move data in and out of a Kinvey collection is by getting a reference to the apps backend collection (named testObjects), which is lled with instances (each named TestObject) of the data the app wants to move. Thats why youll nd the following code repeated three times in Test Drives View Controller (once for the add, once for the load, and once for the delete):
KCSCollection *testObjects = [KCSCollection collectionFromString:@"testObjects" ofClass:[TestObject class]]; KCSAppdataStore *store = [KCSAppdataStore storeWithCollection:testObjects options:nil];
To support these statements it is required to have a data object class (TestObject). To see how these les are written in the sample project, click on TestObject.h le and TestObject.m in the Navigator pane. If you were to supply these les in your own app, you would click File > New File, and specify Objective-C class, which would be a subclass of NSObject. Then you would type in the code, with a property for each column in the Kinvey backend collection (including one for the objects id). As mentioned earlier, your app also needs to authenticate itself to Kinvey, which is handled by AppDelegate.h and AppDelgate.m. These les are created by Xcode when you create a new project, and start out with just a stub implementation. Look in the sample app source
35
les for code to copy and paste. For both the save and load operations, however, moving the data in and out of a backend collection is only part of the work. Table 1 lists all the functions that implements the save and load in the ViewController.m le, along with pointers to its corresponding block of implementation source code. (For each function, its corresponding code begins with the Starts at line and ends with the Ends at line.) Refer to Appendix 1 to nd the actual source code. Say Hello To Our World The key takeaway from all this is that making an app is a worthwhile thing to do for anyone with a clever idea and a working knowledge of Objective-C. The proof is in the hundreds of apps succeeding in the market every day, many written by people working on their own and who never wrote an app before in their lives. As with anything else, practice does make perfect. But hopefully with all the resources available, and the knowledge gained from this ebook, you have already started down the path toward joining the growing legions of iOS app developers. If so, we welcome you!
Table 1: Save and Load Implementation Details of Kinvey Test Drive Sample App
36 1
// // // // // // // #import "ViewController.h" #import "TestObject.h" #define CREATE_NEW_ENTITY_ALERT_VIEW 100 @interface ViewController () @property (nonatomic, strong) NSArray* objects; @end @implementation ViewController - (IBAction)add:(id)sender { UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Create a New Entity" message:@"Enter a title for the new entity" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Save", nil]; alert.alertViewStyle = UIAlertViewStylePlainTextInput; alert.tag = CREATE_NEW_ENTITY_ALERT_VIEW; [alert show]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex Created by Michael Katz on 11/12/12. Copyright (c) 2012-2013 Kinvey. All rights reserved. ViewController.m Kinvey Quickstart
37
{ if (alertView.tag == CREATE_NEW_ENTITY_ALERT_VIEW) { if (buttonIndex == alertView.firstOtherButtonIndex) { // Define an instance of our test object TestObject *testObject = [[TestObject alloc] init]; // This is the data we'll save testObject.name = [[alertView textFieldAtIndex:0] text]; // Get a reference to a backend collection called "testObjects", which is filled with // instances of TestObject KCSCollection *testObjects = [KCSCollection collectionFromString:@"testObjects" ofClass:[TestObject class]]; // Create a data store connected to the collection, in order to save and load TestObjects KCSAppdataStore *store = [KCSAppdataStore storeWithCollection:testObjects options:nil]; // Save our instance to the store [store saveObject:testObject withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil) { // Right now just pop-up an alert about what we got back from Kinvey during // the save. Normally you would want to implement more code here if (errorOrNil == nil && objectsOrNil != nil) { //save is successful! UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Save worked!" message:[NSString stringWithFormat:@"Saved: '%@'",[objectsOrNil[0] name]] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
38
[alert show]; self.objects = [@[testObject] arrayByAddingObjectsFromArray:_objects]; [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic]; } else { //save failed UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Save failed" message:[errorOrNil localizedDescription] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } } withProgressBlock:nil]; } } }
- (IBAction)load:(id)sender { // Get a reference to a backend collection called "testObjects", which is filled with // instances of TestObject KCSCollection *testObjects = [KCSCollection collectionFromString:@"testObjects" ofClass:[TestObject class]]; // Create a data store connected to the collection, in order to save and load TestObjects
39
KCSAppdataStore *store = [KCSAppdataStore storeWithCollection:testObjects options:nil]; KCSQuery* query = [KCSQuery query]; [query addSortModifier:[[KCSQuerySortModifier alloc] initWithField:KCSMetadataFieldLastModifiedTime inDirection:kKCSDescending]]; // This will load the saved 12345 item from the backend [store queryWithQuery:query withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil) { [sender endRefreshing]; // Right now just pop-up an alert about what we got back from Kinvey during // the load. Normally you would want to implement more code here if (errorOrNil == nil && objectsOrNil != nil) { //load is successful! _objects = objectsOrNil; [self.tableView reloadData]; } else { //load failed UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Load failed" message:[errorOrNil localizedDescription] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } } withProgressBlock:nil]; } #pragma mark - View Controller - (void)viewDidLoad
40
{ [super viewDidLoad]; _objects = @[]; [self.refreshControl addTarget:self action:@selector(load:) forControlEvents:UIControlEventValueChanged]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self load:nil]; }
#pragma mark - Table View Stuff - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsIn Section:(NSInteger)section { return _objects.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"aCell"]; cell.textLabel.text = [_objects[indexPath.row] name]; return cell; }
41
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleDelete; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { TestObject* objToDelete = [_objects objectAtIndex:indexPath.row]; NSMutableArray* newObjects self.objects = newObjects; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; // Get a reference to a backend collection called "testObjects", which is filled with // instances of TestObject KCSCollection *testObjects = [KCSCollection collectionFromString:@"testObjects" ofClass:[TestObject class]]; // Create a data store connected to the collection, in order to save and load TestObjects KCSAppdataStore *store = [KCSAppdataStore storeWithCollection:testObjects options:nil]; // Remove our instance from the store = [_objects mutableCopy]; [newObjects removeObjectAtIndex:indexPath.row];
42
[store removeObject:objToDelete withCompletionBlock:^(NSArray *objectsOrNil, NSError *errorOrNil) { if (errorOrNil == nil && objectsOrNil != nil) { //delete is successful! UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Delete successful!" message:nil delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } else { //delete failed UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Delete failed" message:[errorOrNil localizedDescription] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } } withProgressBlock:nil]; } } @end
Written by Randall Cronk Since 1990, Randall has helped over 250 high-tech companies convey the value of what they do through white papers, web content, brochures, case studies and articles. Based today in downtown Boston, he was previously a vice president with Regis McKenna where he ran the Digital Equipment account. Michael Katz Michael has always been a programmer. In college he detoured into modeling the brain, but eventually found his way back into software development, doing hard-core desktop Java programming. But since 2010, he has developed mobile apps and software. He is also the author of a forthcoming iOS networking book, being published by Manning Publications later this year.
What is Kinvey? Kinvey makes a fully-featured Backend as a Service solution, oering 3rd party data integrations, multi-platform support, push notications, and custom business logic on a platform where it's free to get started and you only pay when your app is successful.