Slide 1

Slide 1 text

Parse for iOS Rapid web-backing services

Slide 2

Slide 2 text

TONIGHT ONLY • Introduction to Parse • Benefits & Drawbacks • Consuming web services in iOS • Coding with the Parse Framework • Demo! • Wrap-Up: Additional features Actually also available on the web any time

Slide 3

Slide 3 text

Me • Isaac Schmidt @wryphonedev [email protected] • Indie dev, general tech enthusiast. • 3 years with iOS. Ask me about my apps!

Slide 4

Slide 4 text

• Parse is a commercial platform for developing highly abstracted web services (e.g., simple cloud based persistence, or a new social network). • Parse provides SDKs for mobile devs, including a native Objective-C framework for iOS. • Allows rapid development of app-backing web services by obscuring many aspects otherwise required to develop and deploy web-service fueled apps. Overview of Parse

Slide 5

Slide 5 text

What & How • If you’ve worked with CoreData and/or iCloud, you’ll find Parse very simple to introduce into your apps. • Actually simpler to implement a trivial persistence solution with Parse than either...

Slide 6

Slide 6 text

Limitations • Dependency on Parse’s platform. • Parse is a black box. • Essentially no custom logic in your web services. • Schema-less data modeling (can be a +).

Slide 7

Slide 7 text

iOS Data Landscape • CoreData • iCloud • File System • 3rd Party/Commercial Web Services • Custom Web Services

Slide 8

Slide 8 text

Local Remote CoreData File System iCloud Sandboxed Access Controlled iOS App Data Model Parse Self-Rolled Web Service 3rd Party Content Providers

Slide 9

Slide 9 text

General Benefits • Avoid overhead of deploying custom web services: No servers to configure or maintain, no time spent implementing support for users, queries, or parsing in server or client code. • Until you’re making 1,000,000 API requests a month, VC’s are paying for your EC2 hosting. • Not sandboxed

Slide 10

Slide 10 text

Specific iOS Features • Provides network reachability and caches network-fetched content by default. • You essentially only interact with Objective-C model objects in your code.

Slide 11

Slide 11 text

• Establish a network connection • Define and obtain a user reference • Authenticate the user to a web service • Query the web service • Parse response to produce results • Respond to results (eg, update UI or handle error condition) • Authenticate user if required • Query the web service • Respond to results (eg, update UI or handle error condition) Traditional w/ Parse Required Steps for Consuming Web Services

Slide 12

Slide 12 text

Working with Parse • Create an app ID on parse.com • Add, link, and import the framework • Initialize Parse in your project with a call containing your app ID • Begin interacting with Parse objects

Slide 13

Slide 13 text

Working with Parse • Most Parse API calls come in sync and async flavors • save / saveInBackground • getObject / getObjectInBackground • saveEventually (will save when network permits) • Completion handling with delegate callbacks or blocks • Today’s discussion is block-centric

Slide 14

Slide 14 text

Parse Objects • PFUser & PFACL • PFObject • PFFile • PFQuery • PFPush • PFGeoPoint

Slide 15

Slide 15 text

PFObject • PFObject • Attributes are assigned as key-value pairs • Values must be JSON-encodable • Strings, numbers, arrays, dictionaries • Consider a PFObject a model object (eg, NSManagedObject or NSObject subclass)

Slide 16

Slide 16 text

PFObject PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"]; [gameScore setObject:[NSNumber numberWithInt:1337] forKey:@"score"]; [gameScore setObject:@"Joe" forKey:@"playerName"]; [gameScore setObject:[NSNumber numberWithBool:NO] forKey:@"cheatMode"]; [gameScore save]; •Model Class created lazily •createdAt & updatedAt attributed implicitly •Each object has unique ID •Relationships are defined by associations drawn in code (schema-less)

Slide 17

Slide 17 text

PFUser • Secure and simple approach to “user” management • Hooks for linking Twitter/Facebook accounts • Anonymous/default users • [PFUser currentUser] singleton - (void)myMethod { PFUser *user = [PFUser user]; user.username = @"my name"; user.password = @"my pass"; user.email = @"[email protected]"; // other fields can be set just like with PFObject [user setObject:@"415-555-0101" forKey:@"phone"]; [user signUpInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { if (!error) { // Hooray! Let them use the app now. } else { NSString *errorString = [[error userInfo] objectForKey:@"error"]; // Show the errorString somewhere and let the user try again. } }]; }

Slide 18

Slide 18 text

Access Control w/ PFACL • Simple access-control scenario • You should almost always implement a default ACL, eg: [PFUser enableAutomaticUser]; PFACL *defaultACL = [PFACL ACL]; // Optionally enable public read access while disabling public write access. // [defaultACL setPublicReadAccess:YES]; [PFACL setDefaultACL:defaultACL withAccessForCurrentUser:YES]; • enableAutomaticUser

Slide 19

Slide 19 text

PFQuery • Query/Fetch mechanism • getObjectWithID for specific object • findObjects for searches

Slide 20

Slide 20 text

PFQuery Example PFQuery *query = [PFQuery queryWithClassName:@"GameScore"]; [query whereKey:@"playerName" equalTo:@"Isaac Schmidt"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { if (!error) { // The find succeeded. NSLog(@"Successfully retrieved %d scores.", objects.count); } else { // Log details of the failure NSLog(@"Error: %@ %@", error, [error userInfo]); } }]; Basic Find Query Compound Query PFQuery *lotsOfWins = [PFQuery queryWithClassName:@"Player"]; [lotsOfWins whereKey:@"wins" greaterThan:[NSNumber numberWithInt:150]]; PFQuery *fewWins = [PFQuery queryWithClassName:@"Player"]; [lotsOfWins whereKey:@"wins" lessThan:[NSNumber numberWithInt:5]]; PFQuery *query = [PFQuery orQueryWithSubqueries:[NSArray arrayWithObjects:fewWins,lotsOfWins,nil]]; [query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) { // results contains players with lots of wins or only a few wins. }];

Slide 21

Slide 21 text

Additional PFQuery Features • Dictate caching policy • query.cachePolicy = kPFCachePolicyNetworkElseCache • Determine if a given object exists in cache • BOOL existsInCache = [query hasCachedResult] • Count objects matching query without fetching them • Use countObjects instead of findObjects

Slide 22

Slide 22 text

Demo! • Bake a rich-media-web-backed-social- network in 10 minutes (or less!)

Slide 23

Slide 23 text

Additional Features • Push Notifications • Initiate push notifications to groups or individuals in app or via web interface • User Interface • PFQueryTableViewController simplifies presenting lists-by-query • E-Mail Verification & Password Resets

Slide 24

Slide 24 text

Reminders • Be careful what you gather and store • Users don’t like to discover that their address books have been uploaded. • If you must upload personal info, hash it first. • Maintain a transparent privacy policy. • Side note: Be careful what you NSLog! • Handle errors gracefully • It’s always exciting to move to the next feature. Resist the urge.

Slide 25

Slide 25 text

Wrap Up • Great iOS API documentation, starter, and sample projects on parse.com • Responsive to questions • Find this presentation and sample code on cocoaheadsnyc.org