Browse files

Edit bitly

  • Loading branch information...
1 parent 0397110 commit dd5cdc3b8f2d43676a5406569ee4a861e60166e1 @msv committed Feb 26, 2013
Showing with 1,296 additions and 1,296 deletions.
  1. +1,227 −0 ios/code_camp.html
  2. +69 −609 ios/codecamp.html
  3. +0 −687 ios/iOS_Meetup.html
View
1,227 ios/code_camp.html
@@ -0,0 +1,1227 @@
+<html>
+ <head>
+ <title>StackMob - Adding a Backend to your iOS App</title>
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
+ <script type="text/javascript" src="http://static.stackmob.com/js/json2-min.js"></script>
+ <script type="text/javascript" src="http://static.stackmob.com/js/underscore-1.3.3-min.js"></script>
+ <script type="text/javascript" src="http://static.stackmob.com/js/backbone-0.9.2-min.js"></script>
+ <script type="text/javascript" src="http://static.stackmob.com/js/stackmob-js-0.2.1-min.js"></script>
+ <script type="text/javascript" src="http://static.stackmob.com/resources/js/jsonFormatter-0.1.0-min.js"></script>
+ <script type="text/javascript" src="stackmob-debug.js"></script>
+
+ <!-- Include required JS files -->
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shCore.js"></script>
+
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushJScript.js"></script>
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushXml.js"></script>
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushJava.js"></script>
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushCpp.js"></script>
+ <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushObjC.js"></script>
+
+ <link href="../syntaxhighlighter/styles/shCoreMidnight.css" rel="stylesheet" type="text/css" />
+ <link href="../syntaxhighlighter/styles/shThemeMidnight.css" rel="stylesheet" type="text/css" />
+
+ <style type="text/css">
+ .syntaxhighlighter {
+ margin: 0px !important; padding-top: 15px; padding-bottom: 15px;
+ border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px;
+
+ }
+ </style>
+
+ <script type="text/javascript">
+ StackMob.init({
+ appName: 'javascript',
+ clientSubdomain: 'stackmob',
+ apiVersion: 0
+ });
+
+ var Todo = StackMob.Model.extend({
+ schemaName: 'todo'
+ });
+
+ var Todos = StackMob.Collection.extend({
+ model: Todo
+ });
+
+ $(document).ready(function() {
+ SyntaxHighlighter.config.tagName = 'code';
+ SyntaxHighlighter.config.toolbar = false;
+ SyntaxHighlighter.all();
+
+ Reveal.addEventListener('stampede', function() {
+ $('#stampede').attr('src', 'http://dl.dropbox.com/u/77348001/stampede.gif');
+ });
+ });
+ </script>
+
+ <link rel="stylesheet" href="../reveal.js/css/reset.css">
+ <link rel="stylesheet" href="../reveal.js/css/main.css">
+ <style type="text/css" media="screen">
+ .button, .button a
+{
+ background: #98be47;
+ background: linear-gradient(top, #a8cf43, #98be47);
+ background: -moz-linear-gradient(top, #a8cf43, #98be47);
+ background: -ms-linear-gradient(top, #a8cf43, #98be47);
+ background: -o-linear-gradient(top, #a8cf43, #98be47);
+ background: -webkit-linear-gradient(top, #a8cf43, #98be47);
+ border: 1px solid #8cac42;
+ border-bottom-color: #7b9b36;
+ border-radius: 4px;
+ border-top-color: #94b146;
+ box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
+ color: #fff !important;
+ cursor: pointer;
+ font-family: "Helvetica Neue", Arial, sans-serif;
+ font-size: 26px;
+ font-weight: bold;
+ moz-border-radius: 4px;
+ moz-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
+ ms-border-radius: 4px;
+ ms-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
+ o-border-radius: 4px;
+ o-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
+ padding: 6px 14px;
+ text-decoration: none;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .4);
+ webkit-border-radius: 4px;
+ webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
+}
+.button:hover, .button a:hover
+{
+ background: #67a215;
+ background: linear-gradient(top, #9dbf46, #67a215);
+ background: -moz-linear-gradient(top, #9dbf46, #67a215);
+ background: -ms-linear-gradient(top, #9dbf46, #67a215);
+ background: -o-linear-gradient(top, #9dbf46, #67a215);
+ background: -webkit-linear-gradient(top, #9dbf46, #67a215);
+ border: 1px solid #699631;
+ border-bottom-color: #457119;
+ border-top-color: #6d9e34;
+ color: rgba(250, 250, 250, .96);
+ text-decoration: none;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
+}
+.button:active, .button a:active
+{
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
+ moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
+ ms-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
+ o-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
+ padding: 4px 14px 7px;
+ webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
+}
+.button.blue, .button.blue a
+{
+ background: #6bbad7;
+ background: linear-gradient(top, #76cced, #6bbad7);
+ background: -moz-linear-gradient(top, #76cced, #6bbad7);
+ background: -ms-linear-gradient(top, #76cced, #6bbad7);
+ background: -o-linear-gradient(top, #76cced, #6bbad7);
+ background: -webkit-linear-gradient(top, #76cced, #6bbad7);
+ border: 1px solid #4ca8ca;
+ border-bottom-color: #4c9bb9;
+ border-top-color: #4cb2da;
+}
+.button.blue:hover, .button.blue a:hover
+{
+ background: #2c9cc6;
+ background: linear-gradient(top, #3cb7e5, #2c9cc6);
+ background: -moz-linear-gradient(top, #3cb7e5, #2c9cc6);
+ background: -ms-linear-gradient(top, #3cb7e5, #2c9cc6);
+ background: -o-linear-gradient(top, #3cb7e5, #2c9cc6);
+ background: -webkit-linear-gradient(top, #3cb7e5, #2c9cc6);
+ border: 1px solid #0083b4;
+ border-bottom-color: #00709b;
+ border-top-color: #0092ca;
+}
+
+#stackmoblogo {
+ position: fixed;
+ top: 20px;
+ left: 20px;
+}
+
+.line { font-size: 50px ! important; }
+.logo { width: 400px; }
+.pic { height: 300px; }
+.big35 { font-size: 35px;}
+.big50 { font-size: 50px;}
+.big75 { font-size: 75px;}
+.big100 { font-size: 100px;}
+.top15 { margin-top: 15px; }
+.top25 { margin-top: 25px; }
+.top35 { margin-top: 35px; }
+.top50 { margin-top: 50px; }
+.top75 { margin-top: 75px; }
+.top100 { margin-top: 100px; }
+.lineSpace { line-height: 1.4em }
+.moreLineSpace { line-height: 2.0em }
+ </style>
+
+ </head>
+ <body>
+ <div id="stackmoblogo"><img src="../images/stackmob_logo.png"/></div>
+ <div id="reveal">
+ <div class="state-background"></div>
+
+ <div class="slides">
+ <section>
+ <h2>Adding a Server-Side Backend to your iOS Application</h2>
+ <!-- <h3 class="inverted">StackMob &amp; Objective-C</h3> -->
+ <!-- <p><span style="font-size: 24px;">(uses Backbone.js)</span></p> -->
+ <p style="margin-top: 100px;">
+ <p>Matt Vaznaian | <a href="http://www.twitter.com/mvaznaian" target="_blank">@_mattvaz</a></p>
+ <p><a href="http://www.stackmob.com" target="_blank">stackmob.com</a> | <a href="http://www.twitter.com/stackmob">@stackmob</a> | #stackmob</p>
+ </p>
+ </section>
+ <section>
+ <h2>Matt Vaznaian</h2>
+ <h3>matt@stackmob.com</h3>
+ <h3>@_mattvaz</h3>
+ </section>
+
+ <section>
+ <h2>A Brief History of Building your backend</h2>
+
+ <section>
+ </section>
+
+ <section>
+ <h3>Database</h3>
+ <img src="https://dl.dropbox.com/u/79464649/oracle.jpg" />
+ <img src="https://dl.dropbox.com/u/79464649/mysql-big.gif" />
+ </section>
+
+ <section>
+ <h3>Hardware</h3>
+ <img src="https://dl.dropbox.com/u/79464649/300px-Dell_Logo.svg_1.png" />
+ <img src="https://dl.dropbox.com/u/79464649/intel-logo-300x198.jpg" />
+ </section>
+
+ <section>
+ <h3>Cloud Store</h3>
+ <img width=350px src="https://dl.dropbox.com/u/79464649/amazon.png" />
+ <img width=300px src="https://dl.dropbox.com/u/79464649/iCloud.png" />
+ </section>
+
+ <section>
+ <h3>Software Layer</h3>
+ <img src="https://dl.dropbox.com/u/79464649/heroku.jpg" />
+ <img src="https://dl.dropbox.com/u/79464649/appengine-logo.png" />
+ </section>
+
+ <section>
+ <h3>Platform</h3>
+ <p><img width=600px src="../images/stackmob_fulllogo_white.png"/></a></p>
+ </section>
+
+ </section>
+
+ <section>
+ <h2>StackMob: Who are we?</h2>
+
+ <ul>
+ <li class="big50 lineSpace">Mobile Backend Platform.</li>
+ <li class="big50 lineSpace">Lowering barrier of entry.</li>
+ <li class="big50 lineSpace">Focus on your user experience.</li>
+ <li class="big50 lineSpace">Access to "big company" backend power.</li>
+ <li class="big50 lineSpace">Develop. Scale. Analytics. Revisioning.</li>
+ </ul>
+
+ </section>
+
+ <section>
+ <h2>StackMob: Who uses us?</h2>
+
+ <p class="big50 lineSpace">We've powered apps:</p>
+ <ul>
+ <li class="big50 lineSpace">Featured in the AppStore</li>
+ <li class="big50 lineSpace">Top 20 in the AppStore</li>
+ <li class="big50 lineSpace">TechCrunch Disrupt</li>
+ <li class="big50 lineSpace">SXSW</li>
+ <li class="big50 lineSpace">Won Startup Weekend</li>
+ <li class="big50 lineSpace">Atari</li>
+ </ul>
+ <p class="big50 lineSpace">Games, Enterprise Apps, Social... </p>
+ </section>
+
+ <section>
+ <h2>The First App You Ever Built</h2>
+ <p>
+ <img src="https://dl.dropbox.com/u/79464649/helloWorld.png"/>
+ </p>
+ </section>
+
+ <section>
+ <h2>NSUserDefaults</h2>
+ <p>
+ <img src="https://dl.dropbox.com/u/79464649/helloMatt.png" />
+ </p>
+ </section>
+
+ <section>
+ <h2>The Next Level</h2>
+
+ <ul>
+ <li class="big50 lineSpace">Access Data From Multiple Devices.</li>
+ <li class="big50 lineSpace">Lots of Features == Lots of Data.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>I could do it myself</h2>
+
+ <img src="https://dl.dropbox.com/u/79464649/headInHands.jpg" />
+ </section>
+
+ <section>
+ <h2>Focus on your user experience!</h2>
+
+ <img src="https://dl.dropbox.com/u/79464649/awesome_note.png" />
+ </section>
+
+ <section>
+ <h2>The StackMob iOS SDK</h2>
+ </section>
+
+
+ <section>
+ <h2>Initialize</h2>
+
+ <pre><code class="brush: objc; toolbar: false; highlight: [2,4]">
+ // AppDelegate.h
+ @class SMClient;
+
+ @property (strong, nonatomic) SMClient *client;
+ </code></pre>
+
+ <pre><code class="brush: objc; toolbar: false; highlight: [2,7,8]">
+ // AppDelegate.m
+ #import "StackMob.h"
+
+ - (BOOL)application:(UIApplication *)application
+ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+ {
+ self.client = [[SMClient alloc] initWithAPIVersion:@"YOUR_API_VERSION"
+ publicKey:@"YOUR_PUBLIC_KEY"];
+
+ return YES;
+ }
+ </code></pre>
+ </section>
+
+
+ <section>
+ <h2>Server-Side Persistence: Create</h2>
+ <section>
+ <a href="javascript:void(0);">Syntax:</a>
+ <pre><code class="brush: objc; toolbar: false;">
+
+ NSManagedObject *newManagedObject = [NSEntityDescription
+ insertNewObjectForEntityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [newManagedObject setValue:self.titleField.text forKey:@"title"];
+ [newManagedObject setValue:[newManagedObject sm_assignObjectId]
+ forKey:[newManagedObject sm_primaryKeyField]];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You created a new object!");
+ }
+ </code></pre>
+
+ </section>
+
+ <section>
+ <a href="javascript:void(0);">Syntax:</a>
+ <pre><code class="brush: objc; toolbar: false; highlight: [1,2,3]">
+
+ NSManagedObject *newManagedObject = [NSEntityDescription
+ insertNewObjectForEntityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [newManagedObject setValue:self.titleField.text forKey:@"title"];
+ [newManagedObject setValue:[newManagedObject sm_assignObjectId]
+ forKey:[newManagedObject sm_primaryKeyField]];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You created a new object!");
+ }
+ </code></pre>
+
+ </section>
+
+ <section>
+ <a href="javascript:void(0);">Syntax:</a>
+ <pre><code class="brush: objc; toolbar: false; highlight: [5,6,7]">
+
+ NSManagedObject *newManagedObject = [NSEntityDescription
+ insertNewObjectForEntityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [newManagedObject setValue:self.titleField.text forKey:@"title"];
+ [newManagedObject setValue:[newManagedObject sm_assignObjectId]
+ forKey:[newManagedObject sm_primaryKeyField]];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You created a new object!");
+ }
+ </code></pre>
+
+ </section>
+
+ <section>
+ <a href="javascript:void(0);">Syntax:</a>
+ <pre><code class="brush: objc; toolbar: false; highlight: [9,10,11,12,13,14,15]">
+
+ NSManagedObject *newManagedObject = [NSEntityDescription
+ insertNewObjectForEntityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [newManagedObject setValue:self.titleField.text forKey:@"title"];
+ [newManagedObject setValue:[newManagedObject sm_assignObjectId]
+ forKey:[newManagedObject sm_primaryKeyField]];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You created a new object!");
+ }
+ </code></pre>
+
+ </section>
+
+ <section>
+ <h2>Aw yeah! Backend Created!</h2>
+
+ <p>
+ <img src="http://dl.dropbox.com/u/9289507/joy.gif" alt=""/>
+ </p>
+ </section>
+
+ </section>
+
+
+ <section>
+ <h2>Read from DB</h2>
+ <a href="javascript:void(0);">Read Item</a>
+ <pre><code class="brush: objc; toolbar: false;">
+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
+
+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [fetchRequest setEntity:entity];
+
+ // set any predicates or sort descriptors, etc.
+
+ NSError *anError = nil;
+
+ NSArray *theResults = [self.managedObjectContext
+ executeFetchRequest:fetchRequest
+ error:&anError];
+ </code></pre>
+
+ </section>
+
+ <section>
+
+ <h2>Update DB</h2>
+ <a href="javascript:void(0);">Update Item</a>
+ <pre><code class="brush: objc; toolbar: false;">
+ [aManagedObject setValue:@"something different" forKey:@"title"];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You saved!");
+ }
+ </code></pre>
+
+ </section>
+
+ <section>
+ <h2>Delete from DB</h2>
+ <a href="javascript:void(0);">Delete Item</a>
+ <pre><code class="brush: objc;">
+ [self.managedObjectContext deleteObject:aManagedObject];
+
+ NSError *error = nil;
+ if (![self.managedObjectContext save:&error]) {
+ NSLog(@"There was an error! %@", error);
+ }
+ else {
+ NSLog(@"You deleted an object!");
+ }
+ </code></pre>
+ </section>
+
+ <section>
+ <h2>Lower Level Datastore API</h2>
+ <ul>
+ <li class="moreLineSpace big50">createObject:inSchema:onSuccess:onFailure:</li>
+ <li class="moreLineSpace big50">readObjectWithId:inSchema:onSuccess:onFailure:</li>
+ <li class="moreLineSpace big50">updateObjectWithId:inSchema:update:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onSuccess:onFailure:</li>
+ <li class="moreLineSpace big50">deleteObjectId:inSchema:onSuccess:onFailure:</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>WOOHOO for CRUD!</h2>
+ <img src="https://dl.dropbox.com/u/79464649/homer_woohoo.jpg" />
+ </section>
+
+ <section>
+ <h2>Core Data Integration</h2>
+ <section>
+ <p class="big50 moreLineSpace">Brought to you by</p>
+ <p class="big75 lineSpace">NSIncrementalStore</p>
+ </section>
+ <section>
+ <img src="../images/inc_store_diagram_1.png" />
+ </section>
+ <section>
+ <img src="../images/inc_store_diagram_2.png" />
+ </section>
+ <section>
+ <img src="../images/inc_store_diagram_3.png" />
+ </section>
+ </section>
+
+ <section>
+ <h2>But I want more than just a datastore in the cloud!</h2>
+
+ <ul>
+ <li class="lineSpace big50">Queries</li>
+ <li class="lineSpace big50">Relate this object to that object</li>
+ <li class="lineSpace big50">User Authentication</li>
+ <li class="lineSpace big50">Push Notifications</li>
+ <li class="lineSpace big50"><img src="../images/f_logo.png"/>
+ <img src="../images/twitter_logo.png"/>
+ </li>
+ </ul>
+ </section>
+
+
+ <section>
+ <h2>Queries</h2>
+
+ <section>
+ <img src="https://dl.dropbox.com/u/79464649/massiveData_dr-evil.jpg" />
+
+ </section>
+
+ <section>
+ <h3>NSPredicate</h3>
+ <pre><code class="brush: objc; toolbar: false; highlight: [9,10]">
+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
+
+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [fetchRequest setEntity:entity];
+
+ // set any predicates or sort descriptors, etc.
+ NSPredicate *equalPredicate = [NSPredicate predicateWithFormat:@"title == %@", self.someTitle];
+ [fetchRequest setPredicate:equalPredicate];
+
+ NSError *anError = nil;
+
+ NSArray *theResults = [self.managedObjectContext
+ executeFetchRequest:fetchRequest
+ error:&anError];
+ </code></pre>
+
+ </section>
+
+ <section>
+ <h3>Comparison Predicates</h3>
+ <ul>
+ <li>==</li>
+ <li>!=</li>
+ <li><</li>
+ <li><=</li>
+ <li>></li>
+ <li>>=</li>
+ <li>IN</li>
+ <li>BETWEEN</li>
+ </ul>
+ </section>
+
+ <section>
+ <h3>Pagination</h3>
+ <pre><code class="brush: objc; toolbar: false; highlight: [9,10,11,12,13]">
+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
+
+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
+ inManagedObjectContext:self.managedObjectContext];
+
+ [fetchRequest setEntity:entity];
+
+ // set any predicates or sort descriptors, etc.
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
+ initWithKey:@"title"
+ ascending:YES];
+ NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
+ [fetchRequest setSortDescriptors:sortDescriptors];
+
+ NSError *anError = nil;
+
+ NSArray *theResults = [self.managedObjectContext
+ executeFetchRequest:fetchRequest
+ error:&anError];
+ </code></pre>
+
+ </section>
+
+ <section>
+ <h3>Lower Level Datastore API</h3>
+ <pre><code class="brush: objc;">
+ SMQuery *query = [[SMQuery alloc] initWithSchema:@"todo"];
+ [q where:@"age" isGreaterThan:25];
+
+ [[[SMClient defaultClient] dataStore] performQuery:query
+ onSuccess:^(NSArray *results) {
+ // Handle success
+ } onFailure:^(NSError *error) {
+ // Handle error
+ }
+ ];
+ </code></pre>
+ </section>
+
+ </section>
+
+ <section>
+ <h2>Relationships</h2>
+ <img height=500px src="https://dl.dropbox.com/u/79464649/holdingHands.jpg" />
+ </section>
+
+ <section>
+ <h2>User Authentication</h2>
+ <section>
+ <img src="http://dl.dropbox.com/u/77348001/calving_hobbes_password.gif" alt=""/>
+ </section>
+
+ <section>
+ <h3>Login</h2>
+ <pre><code class="brush: objc;">
+ [[SMClient defaultClient] loginWithUsername:self.usernameField.text
+ password:self.passwordField.text
+ onSuccess:^(NSDictionary *results) {
+ // Handle success
+ } onFailure:^(NSError *error) {
+ // Handle failure
+ }];
+ </code></pre>
+ </section>
+
+ <section>
+ <h3>Check Login Status</h2>
+ <pre><code class="brush: objc;">
+ [[SMClient defaultClient] getLoggedInUserOnSuccess:^(NSDictionary *result) {
+ self.statusLabel.text = [NSString stringWithFormat:@"Hello, %@",
+ [result objectForKey:@"username"]];
+ } onFailure:^(NSError *error) {
+ NSLog(@"No user found");
+ }];
+ </code></pre>
+ </section>
+
+ <section>
+ <h3>Logout</h2>
+ <pre><code class="brush: objc;">
+ [[SMClient defaultClient] logoutOnSuccess:^(NSDictionary *result) {
+ // Handle success
+ } onFailure:^(NSError *error) {
+ // Handle error
+ }];
+ </code></pre>
+ </section>
+
+ <section>
+ <h3>Password Management</h3>
+ <ul>
+ <li class="moreLineSpace big50">Forgotten Passwords</li>
+ <li class="moreLineSpace big50">Reset Password</li>
+ </ul>
+
+ </section>
+ </section>
+ <!--
+ <section>
+ <h2>Security &rarr; OAuth 2.0</h2>
+
+ <ul>
+ <li>Industry Standard: OAuth 1.0/2.0</li>
+ <li>Public/Private Keys identify your app's requests</li>
+ <li>FB/Twitter: OAuth 2.0. Username/Password</li>
+ <li>In current JS SDK for pre-trials</li>
+ </ul>
+
+ </section>
+ -->
+ <section>
+ <h2>Access Controls</h2>
+ <ul>
+ <li class="moreLineSpace big50">Share objects to certain users.</li>
+ <li class="moreLineSpace big50">Only authenticated users should be able to access certain data.</li>
+ <li class="moreLineSpace big50">Limit visibility.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Push</h2>
+ <pre><code class="brush: objc;">
+ // In application:didFinishLaunchingWithOptions:
+
+ // Assuming you declared the variable "SMPushClient *pushclient;"
+ pushClient = [[SMPushClient alloc] initWithAPIVersion:@"0"
+ publicKey:@"publicKey" privateKey:@"privateKey"];
+
+ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
+ (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
+ UIRemoteNotificationTypeSound)];
+ </code></pre>
+ <pre><code class="brush: objc; highlight: [11,12]">
+ - (void)application:(UIApplication *)app
+ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
+ {
+ NSString *token = [[deviceToken description]
+ stringByTrimmingCharactersInSet:[NSCharacterSet
+ characterSetWithCharactersInString:@"<>"]];
+
+ token = [[token componentsSeparatedByString:@" "]
+ componentsJoinedByString:@""];
+
+ [pushClient registerDeviceToken:token withUser:@"randomuser"
+ onSuccess:createdSuccessBlock onFailure:createdFailureBlock];
+ }
+ </code></pre>
+ </section>
+ <section>
+ <h2>Facebook and Twitter Authentication</h2>
+ <ul>
+ <li class="lineSpace">createUserWithFacebookToken:onSuccess:onFailure:</li>
+ <li class="lineSpace">loginWithFacebookToken:onSuccess:onFailure:</li>
+ <li class="lineSpace">updateFacebookStatusWithMessage:onSuccess:onFailure:</li>
+ <li class="lineSpace">getLoggedInUserFacebookInfoWithOnSuccess:onFailure:</li>
+ </ul>
+ <br/>
+ <br/>
+ <ul>
+ <li class="lineSpace">createUserWithTwitterToken:twitterSecret:onSuccess:onFailure:</li>
+ <li class="lineSpace">loginWithTwitterToken:twitterSecret:onSuccess:onFailure:</li>
+ <li class="lineSpace">updateTwitterStatusWithMessage:onSuccess:onFailure:</li>
+ <li class="lineSpace">getLoggedInUserTwitterInfoOnSuccess:onFailure:</li>
+ </ul>
+ </section>
+ <section>
+
+ <section>
+ <h2>Even more flexibility: Custom Code</h2>
+ <ul>
+ <li class="moreLineSpace big50">Java/Scala Server Side SDK.</li>
+ <li class="moreLineSpace big50">Write Code - StackMob REST-ifies it.</li>
+ <li class="moreLineSpace big50">iOS can execute your server code via REST API!</li>
+ <li class="moreLineSpace big50">iOS receives your custom JSON response too.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Call Custom Code from iOS App!</h2>
+ <pre><code class="brush: objc;">
+ [[SMCustomCodeRequest *ccRequest = SMCustomCodeRequest alloc]
+ initGetRequestWithMethod:@"hello_world" body:nil];
+
+ [[SMClient defaultClient] performCustomCodeRequest:ccRequest
+ onSuccess:^(NSURLRequest request, NSHTTPURLResponse response, id JSON) {
+ // Returns a JSON body specified by the custom code method
+ } onFailure:^(NSURLRequest request, NSHTTPURLResponse response, NSError *error, id JSON) {
+ // Handle failure
+ }
+ ];
+ </code></pre>
+ </section>
+
+ <section>
+ <h2>Custom Code Example</h2>
+
+<pre><code class="brush: java">
+//Java
+public class HelloWorldExample implements CustomCodeMethod {
+
+ @Override
+ public String getMethodName() {
+ return "hello_world";
+ }
+
+ @Override
+ public ResponseToProcess execute(...) {
+
+ //Do fancy server side things
+
+ Map&lt;String, String&gt; json =
+ new HashMap&lt;String, String&gt;();
+ json.put("msg", "hello world!");
+ return new ResponseToProcess(..., json);
+ }
+}
+</code></pre>
+ </section>
+
+ <section>
+ <h2>Defines your REST endpoint</h2>
+ <p><code>http://api.mob1.stackmob.com/hello_world</code></p>
+<pre><code class="brush: java; highlight: [6]">
+//Java
+public class HelloWorldExample implements CustomCodeMethod {
+
+ @Override
+ public String getMethodName() {
+ return "hello_world";
+ }
+
+ ...
+}
+</code></pre>
+ </section>
+
+ <section>
+ <h2>Defines your return JSON</h2>
+ <p><code>{ msg: "hello world!" }</code></p>
+<pre><code class="brush: java; highlight: [11]">
+//Java
+public class HelloWorldExample implements CustomCodeMethod {
+ ...
+ @Override
+ public ResponseToProcess execute(...) {
+
+ //Do fancy server side things
+
+ Map&lt;String, String&gt; json =
+ new HashMap&lt;String, String&gt;();
+ json.put("msg", "hello world!");
+ return new ResponseToProcess(..., json);
+ }
+}
+</code></pre>
+ </section>
+
+ </section>
+
+ <section>
+ <h2>Development &amp; Production Environments</h2>
+ <ul>
+ <li class="moreLineSpace big50">Different databases.</li>
+ <li class="moreLineSpace big50">Only deploy when you're ready!</li>
+ <li class="moreLineSpace big50">Easy rollout/rollback.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>API Versions</h2>
+ <ul>
+ <li class="moreLineSpace big50">Backwards support old clients.</li>
+ <li class="moreLineSpace big50">Concurrently run different versions of your custom code/schemas.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Time to Re-Market</h2>
+ <ul>
+ <li class="moreLineSpace big50">Change configurations through the Dashboard.</li>
+ <li class="moreLineSpace big50">Instantly reflected in your application.</li>
+ <li class="moreLineSpace big50">No need to resubmit to the App Store.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>The future of the iOS SDK</h2>
+ <img height=500px src="https://dl.dropbox.com/u/79464649/future.jpg" />
+
+ </section>
+
+ <section>
+ <h2>Open Sourced SDKs</h2>
+
+ <ul>
+ <li class="moreLineSpace big50">iOS</li>
+ <li class="moreLineSpace big50">Android</li>
+ <li class="moreLineSpace big50">Javascript</li>
+ <li class="moreLineSpace big50">Download them today!</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Adding a backend with StackMob</h2>
+ <ul>
+ <li class="moreLineSpace big50">Simple.</li>
+ <li class="moreLineSpace big50">Seamless.</li>
+ <li class="moreLineSpace big50">Flexible.</li>
+ <li class="moreLineSpace big50">Powerful.</li>
+ <li class="moreLineSpace big50">Free &rarr; Grow.</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Backend Services</h2>
+ <ul>
+ <li class="lineSpace">User Authentication</li>
+ <li class="lineSpace">Datastore</li>
+ <li class="lineSpace">Security</li>
+ <li class="lineSpace">GeoSpatial</li>
+ <li class="lineSpace">Push</li>
+ <li class="lineSpace">Hosting</li>
+ <li class="lineSpace">Social Integration</li>
+ <li class="lineSpace">Custom Server Side Code</li>
+ <li class="lineSpace">Analytics</li>
+ <li class="lineSpace">...</li>
+ </ul>
+ </section>
+
+ <section>
+ <h2>Thank you!</h2>
+ <p><img width="400px" src="../images/hercmanpic.png"/></p>
+
+ </section>
+
+ <section>
+ <h2>Try it out!</h2>
+ <a class="lineSpace big50" href="https://developer.stackmob.com">https://developer.stackmob.com</a>
+ <br/>
+ <br/>
+ <h2>Get the Slides</h2>
+ <a class="lineSpace big50" href="http://bit.ly/OKbXHM">http://bit.ly/OKbXHM</a>
+
+ </section>
+
+ <section>
+ <h2>Acknowledgements</h2>
+ <ul>
+ <li>Reveal.js and Styles - Hakim El Hattab </li>
+ <li>MySQL, Oracle, AWS, Dell, Intel, Google App Engine, Heroku - Google Images</li>
+ <li>Head In Hands, Awesome Note, Dr. Evil, Holding Hands, Future - Google Images</li>
+ <li>Cookie Monster - Sesame Street</li>
+ <li>Calvin &amp; Hobbes - Bill Watterson</li>
+
+ </ul>
+ </section>
+
+ </div>
+
+ <!-- The navigational controls UI -->
+ <aside class="controls">
+ <a class="left" href="#">&#x25C4;</a>
+ <a class="right" href="#">&#x25BA;</a>
+ <a class="up" href="#">&#x25B2;</a>
+ <a class="down" href="#">&#x25BC;</a>
+ </aside>
+
+ <!-- Displays presentation progress, max value changes via JS to reflect # of slides -->
+ <div class="progress"><span></span></div>
+
+ </div>
+ <script type="text/javascript" src="../reveal.js/js/reveal.js"></script>
+ <script type="text/javascript">
+ Reveal.initialize({
+ // Display controls in the bottom right corner
+ controls: true,
+
+ // Display a presentation progress bar
+ progress: true,
+
+ // If true; each slide will be pushed to the browser history
+ history: true,
+
+ // Loops the presentation, defaults to false
+ loop: false,
+
+ // Flags if mouse wheel navigation should be enabled
+ mouseWheel: false,
+
+ // UI style
+ theme: 'default', // default/neon
+
+ rollingLinks: false,
+
+ // Transition style
+ transition: 'default' // default/cube/page/concave/linear(2d)
+ });
+ </script>
+
+ </body>
+</html>
+
+
+
+<!--
+
+
+
+
+
+
+ <section>
+ <h2>This. But for you.</h2>
+
+ <p>This isn't just for Facebook, Twitter, or the big guys.</p>
+
+ <p>This is for you.</p>
+
+ <p><img width="400px" src="../images/stackmob_logo.png"/></p>
+
+ </section>
+
+
+
+ <section>
+ <section>
+ <h2>Collections</h2>
+ <pre><code class="brush: javascript; highlight: [9,10,13]">
+ //From earlier..
+ var Todo = StackMob.Model.extend({
+ schemaName: 'todo'
+ });
+
+ ...
+
+ //Same as Backbone..
+ var Todos = StackMob.Collection.extend({
+ model: Todo
+ });
+
+ var todos = new Todos();
+ todos.fetch();
+ </code></pre>
+
+ </section>
+ <section>
+ <h2>Fetch your Todos!</h2>
+ <p>var todos = new Todos();</p>
+ <p>todos.fetch();</p>
+
+ <p><input id="fetchcollection" type="button" class="button" value="Fetch your Todos"/></p>
+
+ <textarea id="fetchtodos"></textarea>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#fetchcollection').click(function() {
+ var todos = new Todos();
+ todos.fetch(SMDebug.callbacks('Fetch Todos', 'fetchtodos'));
+ });
+ });
+ </script>
+ </section>
+ </section>
+
+ <section>
+ <section>
+ <h2>Queries: Fetching specific models</h2>
+
+ <p>Getting Finished Todos</p>
+ <pre><code class="brush: javascript; highlight: [1, 5]">
+ var q = new StackMob.Collection.Query();
+ q.equals('done', true);
+
+ var todos = new Todos();
+ todos.query(q, callbacks);
+ </code></pre>
+ </section>
+ <section>
+ <h2>Get Finished Todos</h2>
+<pre><code class="brush: javascript;">
+var q = new StackMob.Collection.Query();
+q.equals('done', true);
+
+var todos = new Todos();
+todos.query(q, callbacks);
+</code></pre>
+ <p><input type="button" class="button" id="querycollection" value="Get Finished Todos"/></p>
+
+ <textarea id="fetchfinishedtodos"></textarea>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#querycollection').click(function() {
+ var q = new StackMob.Collection.Query();
+ q.equals('done', true);
+
+ var todos = new Todos();
+ todos.query(q, SMDebug.callbacks('Query Finished Todos', 'fetchfinishedtodos'));
+ });
+ });
+ </script>
+ </section>
+
+ <section>
+ <h2>Filter Queries</h2>
+<pre><code class="brush: javascript;">
+var q = new StackMob.Collection.Query();
+q.lt('age', 21); //less than
+q.gt('followers', 30); //greater than
+q.notEquals('age', 5); //not equals
+
+var people = new People(); //StackMob.Collection
+people.query(q, callbacks);
+</code></pre>
+ </section>
+ <section>
+ <h2>Ordering/Pagination</h2>
+
+<pre><code class="brush: javascript;">
+var q = new StackMob.Collection.Query();
+q.orderAsc('age'); //order by ascending
+q.setRange(0,4); //pagination first 5 results
+
+var people = new People(); //StackMob.Collection
+people.query(q, callbacks);
+
+</code></pre>
+ </section>
+ <section>
+ <h2>Select Fields (Smaller Payload)</h2>
+<pre><code class="brush: javascript;">
+var q = new StackMob.Collection.Query();
+//select certain fields
+q.select('username').select('age');
+
+var people = new People(); //StackMob.Collection
+people.query(q, callbacks);
+
+</code></pre>
+
+ </section>
+
+ <section>
+ <h2>Select Fields Example</h2>
+<pre><code class="brush: javascript;">
+//q.select('username').select('age');
+
+[{
+ username: 'bob',
+ age: 10
+}, {
+ username: 'jane',
+ age: 15
+}, {
+ username: 'matt',
+ age: 20
+}]
+
+</code></pre>
+ </section>
+
+ </section>
+
+ <section>
+ <section>
+ <h2>Relationships</h2>
+ <img src="http://dl.dropbox.com/u/77348001/userTotodos.png" alt=""/>
+ </section>
+
+ <section>
+ <h2>Relationship: User &rarr; Todos</h2>
+ <ul>
+ <li><a href="https://www.stackmob.com/platform/api/schemas/edit/user" target="blank">Edit User Schema</a></li>
+ <li>Add one-to-many "todos" relationship</li>
+ </ul>
+ <img src="http://dl.dropbox.com/u/77348001/to-do-list-nothing.jpg" alt=""/>
+ </section>
+
+ <section>
+ <h2>Give Todo Items to User</h2>
+ <img src="http://dl.dropbox.com/u/77348001/calvin_and_hobbes_calvin.png" alt=""/>
+<pre><code class="brush: javascript;">
+var todo1 = new Todo({ action: 'take out the trash' });
+var todo2 = new Todo({ action: 'do the laundry' });
+var todo3 = new Todo({ action: 'prepare my slides!' });
+
+var user = new StackMob.User({ username: 'calvin' });
+user.addRelationship('todos', [todo1, todo2, todo3], callbacks);
+</code></pre>
+ </section>
+
+ <section>
+ <h2>Let's try it. But first..</h2>
+ <p>Let's see what "ericktai" looks like:</p>
+ <textarea id="readuser"></textarea>
+ <p><input type="button" id="fetchuser" class="button" value="Fetch User"/></p>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#fetchuser').click(function() {
+ var user = new StackMob.User({ username: 'ericktai' });
+ user.fetch(SMDebug.callbacks('Fetch User', 'readuser'));
+ });
+ });
+ </script>
+ </section>
+
+ <section>
+ <h2>Add Todos to User</h2>
+
+ <textarea id="addtodos"></textarea>
+ <p><input type="button" id="addtodoitems" class="button" value="Add Todos to User"/></p>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#addtodoitems').click(function() {
+ var todo1 = new Todo({ action: 'take out the trash' });
+ var todo2 = new Todo({ action: 'do the laundry' });
+ var todo3 = new Todo({ action: 'prepare my slides!' });
+
+ var user = new StackMob.User({ username: 'ericktai' });
+ user.addRelationship('todos', [todo1, todo2, todo3], SMDebug.callbacks('Add Todos to User', 'addtodos'));
+ });
+ });
+ </script>
+ </section>
+ <section>
+ <h2>Expand: Get Full Related Objects</h2>
+<pre><code class="brush: javascript;">
+//Use StackMob.Model#fetchExpanded
+
+var user = new StackMob.User({ username: 'ericktai' });
+user.fetchExpanded(1, callbacks);
+</code></pre>
+ <textarea id="readuserexpanded"></textarea>
+ <p><input type="button" id="fetchuserexpanded" class="button" value="Fetch Expanded User"/></p>
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#fetchuserexpanded').click(function() {
+ var user = new StackMob.User({ username: 'ericktai' });
+ user.fetchExpanded(1, SMDebug.callbacks('Fetch Expanded User', 'readuserexpanded'));
+ });
+ });
+ </script>
+ </section>
+ </section>
+
+ <section>
+ <section>
+ <h2>User Authentication</h2>
+
+ <img src="http://dl.dropbox.com/u/77348001/calving_hobbes_password.gif" alt=""/>
+ </section>
+
+
+
+-->
View
678 ios/codecamp.html
@@ -1,6 +1,6 @@
<html>
<head>
- <title>StackMob - Adding a Backend to your iOS App</title>
+ <title>StackMob - A Mobile Development Platform for Backend Solutions</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://static.stackmob.com/js/json2-min.js"></script>
<script type="text/javascript" src="http://static.stackmob.com/js/underscore-1.3.3-min.js"></script>
@@ -168,20 +168,15 @@
<div class="slides">
<section>
- <h2>Adding a Server-Side Backend to your iOS Application</h2>
+ <h2>StackMob<br/>A Mobile Backend Platform</h2>
<!-- <h3 class="inverted">StackMob &amp; Objective-C</h3> -->
<!-- <p><span style="font-size: 24px;">(uses Backbone.js)</span></p> -->
<p style="margin-top: 100px;">
<p>Matt Vaznaian | <a href="http://www.twitter.com/mvaznaian" target="_blank">@_mattvaz</a></p>
- <p><a href="http://www.stackmob.com" target="_blank">stackmob.com</a> | <a href="http://www.twitter.com/stackmob">@stackmob</a> | #stackmob</p>
+ <p><a href="http://www.stackmob.com" target="_blank">stackmob.com</a> | <a href="http://www.twitter.com/stackmob">@StackMob</a></p>
</p>
- </section>
- <section>
- <h2>Matt Vaznaian</h2>
- <h3>matt@stackmob.com</h3>
- <h3>@_mattvaz</h3>
- </section>
-
+ </section>
+ <!--
<section>
<h2>A Brief History of Building your backend</h2>
@@ -218,20 +213,9 @@
</section>
</section>
-
- <section>
- <h2>StackMob: Who are we?</h2>
-
- <ul>
- <li class="big50 lineSpace">Mobile Backend Platform.</li>
- <li class="big50 lineSpace">Lowering barrier of entry.</li>
- <li class="big50 lineSpace">Focus on your user experience.</li>
- <li class="big50 lineSpace">Access to "big company" backend power.</li>
- <li class="big50 lineSpace">Develop. Scale. Analytics. Revisioning.</li>
- </ul>
-
- </section>
+ -->
+ <!--
<section>
<h2>StackMob: Who uses us?</h2>
@@ -246,526 +230,75 @@
</ul>
<p class="big50 lineSpace">Games, Enterprise Apps, Social... </p>
</section>
-
+ -->
<section>
<h2>The First App You Ever Built</h2>
<p>
- <img src="https://dl.dropbox.com/u/79464649/helloWorld.png"/>
+ <img width="300px" src="https://dl.dropbox.com/u/79464649/helloWorld.png"/>
</p>
</section>
<section>
<h2>NSUserDefaults</h2>
<p>
- <img src="https://dl.dropbox.com/u/79464649/helloMatt.png" />
+ <img width="300px" src="https://dl.dropbox.com/u/79464649/helloMatt.png" />
</p>
</section>
-
+
<section>
- <h2>The Next Level</h2>
-
- <ul>
- <li class="big50 lineSpace">Access Data From Multiple Devices.</li>
- <li class="big50 lineSpace">Lots of Features == Lots of Data.</li>
- </ul>
+ <h2>Core Data</h2>
+ <p>
+ <img width="600px" src="https://dl.dropbox.com/u/79464649/core-data-model.png" />
+ </p>
</section>
-
+
<section>
- <h2>I could do it myself</h2>
+ <h2>Your New App Idea</h2>
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/databases.jpeg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/lock.jpeg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/geo.jpg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/facebooksm.jpg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/twittersm.jpg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/email.jpeg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/s3.jpg" />
+ <img width="200px" src="https://dl.dropbox.com/u/79464649/scaling.jpeg" />
- <img src="https://dl.dropbox.com/u/79464649/headInHands.jpg" />
- </section>
- <section>
- <h2>Focus on your user experience!</h2>
-
- <img src="https://dl.dropbox.com/u/79464649/awesome_note.png" />
</section>
<section>
- <h2>The StackMob iOS SDK</h2>
- </section>
-
-
- <section>
- <h2>Initialize</h2>
-
- <pre><code class="brush: objc; toolbar: false; highlight: [2,4]">
- // AppDelegate.h
- @class SMClient;
-
- @property (strong, nonatomic) SMClient *client;
- </code></pre>
+ <h2>You could build it yourself</h2>
- <pre><code class="brush: objc; toolbar: false; highlight: [2,7,8]">
- // AppDelegate.m
- #import "StackMob.h"
-
- - (BOOL)application:(UIApplication *)application
- didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.client = [[SMClient alloc] initWithAPIVersion:@"YOUR_API_VERSION"
- publicKey:@"YOUR_PUBLIC_KEY"];
-
- return YES;
- }
- </code></pre>
+ <img width="600px" src="https://dl.dropbox.com/u/79464649/databaseCenter.jpg" />
</section>
-
<section>
- <h2>Server-Side Persistence: Create</h2>
- <section>
- <a href="javascript:void(0);">Syntax:</a>
- <pre><code class="brush: objc; toolbar: false;">
-
- NSManagedObject *newManagedObject = [NSEntityDescription
- insertNewObjectForEntityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [newManagedObject setValue:self.titleField.text forKey:@"title"];
- [newManagedObject setValue:[newManagedObject sm_assignObjectId]
- forKey:[newManagedObject sm_primaryKeyField]];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You created a new object!");
- }
- </code></pre>
-
- </section>
+ <h2>Or...focus on your user experience!</h2>
- <section>
- <a href="javascript:void(0);">Syntax:</a>
- <pre><code class="brush: objc; toolbar: false; highlight: [1,2,3]">
-
- NSManagedObject *newManagedObject = [NSEntityDescription
- insertNewObjectForEntityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [newManagedObject setValue:self.titleField.text forKey:@"title"];
- [newManagedObject setValue:[newManagedObject sm_assignObjectId]
- forKey:[newManagedObject sm_primaryKeyField]];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You created a new object!");
- }
- </code></pre>
-
- </section>
-
- <section>
- <a href="javascript:void(0);">Syntax:</a>
- <pre><code class="brush: objc; toolbar: false; highlight: [5,6,7]">
-
- NSManagedObject *newManagedObject = [NSEntityDescription
- insertNewObjectForEntityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [newManagedObject setValue:self.titleField.text forKey:@"title"];
- [newManagedObject setValue:[newManagedObject sm_assignObjectId]
- forKey:[newManagedObject sm_primaryKeyField]];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You created a new object!");
- }
- </code></pre>
-
- </section>
-
- <section>
- <a href="javascript:void(0);">Syntax:</a>
- <pre><code class="brush: objc; toolbar: false; highlight: [9,10,11,12,13,14,15]">
-
- NSManagedObject *newManagedObject = [NSEntityDescription
- insertNewObjectForEntityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [newManagedObject setValue:self.titleField.text forKey:@"title"];
- [newManagedObject setValue:[newManagedObject sm_assignObjectId]
- forKey:[newManagedObject sm_primaryKeyField]];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You created a new object!");
- }
- </code></pre>
-
- </section>
-
- <section>
- <h2>Aw yeah! Backend Created!</h2>
-
- <p>
- <img src="http://dl.dropbox.com/u/9289507/joy.gif" alt=""/>
- </p>
- </section>
-
+ <img src="https://dl.dropbox.com/u/79464649/awesome_note.png" />
</section>
-
- <section>
- <h2>Read from DB</h2>
- <a href="javascript:void(0);">Read Item</a>
- <pre><code class="brush: objc; toolbar: false;">
- NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
-
- NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [fetchRequest setEntity:entity];
-
- // set any predicates or sort descriptors, etc.
-
- NSError *anError = nil;
-
- NSArray *theResults = [self.managedObjectContext
- executeFetchRequest:fetchRequest
- error:&anError];
- </code></pre>
-
- </section>
-
- <section>
-
- <h2>Update DB</h2>
- <a href="javascript:void(0);">Update Item</a>
- <pre><code class="brush: objc; toolbar: false;">
- [aManagedObject setValue:@"something different" forKey:@"title"];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You saved!");
- }
- </code></pre>
-
- </section>
-
- <section>
- <h2>Delete from DB</h2>
- <a href="javascript:void(0);">Delete Item</a>
- <pre><code class="brush: objc;">
- [self.managedObjectContext deleteObject:aManagedObject];
-
- NSError *error = nil;
- if (![self.managedObjectContext save:&error]) {
- NSLog(@"There was an error! %@", error);
- }
- else {
- NSLog(@"You deleted an object!");
- }
- </code></pre>
- </section>
-
- <section>
- <h2>Lower Level Datastore API</h2>
- <ul>
- <li class="moreLineSpace big50">createObject:inSchema:onSuccess:onFailure:</li>
- <li class="moreLineSpace big50">readObjectWithId:inSchema:onSuccess:onFailure:</li>
- <li class="moreLineSpace big50">updateObjectWithId:inSchema:update:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onSuccess:onFailure:</li>
- <li class="moreLineSpace big50">deleteObjectId:inSchema:onSuccess:onFailure:</li>
- </ul>
- </section>
-
- <section>
- <h2>WOOHOO for CRUD!</h2>
- <img src="https://dl.dropbox.com/u/79464649/homer_woohoo.jpg" />
- </section>
-
- <section>
- <h2>Core Data Integration</h2>
- <section>
- <p class="big50 moreLineSpace">Brought to you by</p>
- <p class="big75 lineSpace">NSIncrementalStore</p>
- </section>
- <section>
- <img src="../images/inc_store_diagram_1.png" />
- </section>
- <section>
- <img src="../images/inc_store_diagram_2.png" />
- </section>
- <section>
- <img src="../images/inc_store_diagram_3.png" />
- </section>
- </section>
-
<section>
- <h2>But I want more than just a datastore in the cloud!</h2>
+ <h2>StackMob To The Rescue</h2>
<ul>
- <li class="lineSpace big50">Queries</li>
- <li class="lineSpace big50">Relate this object to that object</li>
- <li class="lineSpace big50">User Authentication</li>
- <li class="lineSpace big50">Push Notifications</li>
- <li class="lineSpace big50"><img src="../images/f_logo.png"/>
- <img src="../images/twitter_logo.png"/>
- </li>
- </ul>
- </section>
-
-
- <section>
- <h2>Queries</h2>
-
- <section>
- <img src="https://dl.dropbox.com/u/79464649/massiveData_dr-evil.jpg" />
-
- </section>
-
- <section>
- <h3>NSPredicate</h3>
- <pre><code class="brush: objc; toolbar: false; highlight: [9,10]">
- NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
-
- NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [fetchRequest setEntity:entity];
-
- // set any predicates or sort descriptors, etc.
- NSPredicate *equalPredicate = [NSPredicate predicateWithFormat:@"title == %@", self.someTitle];
- [fetchRequest setPredicate:equalPredicate];
-
- NSError *anError = nil;
-
- NSArray *theResults = [self.managedObjectContext
- executeFetchRequest:fetchRequest
- error:&anError];
- </code></pre>
-
- </section>
-
- <section>
- <h3>Comparison Predicates</h3>
- <ul>
- <li>==</li>
- <li>!=</li>
- <li><</li>
- <li><=</li>
- <li>></li>
- <li>>=</li>
- <li>IN</li>
- <li>BETWEEN</li>
- </ul>
- </section>
-
- <section>
- <h3>Pagination</h3>
- <pre><code class="brush: objc; toolbar: false; highlight: [9,10,11,12,13]">
- NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
-
- NSEntityDescription *entity = [NSEntityDescription entityForName:@"Todo"
- inManagedObjectContext:self.managedObjectContext];
-
- [fetchRequest setEntity:entity];
-
- // set any predicates or sort descriptors, etc.
- NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
- initWithKey:@"title"
- ascending:YES];
- NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
- [fetchRequest setSortDescriptors:sortDescriptors];
-
- NSError *anError = nil;
-
- NSArray *theResults = [self.managedObjectContext
- executeFetchRequest:fetchRequest
- error:&anError];
- </code></pre>
-
- </section>
-
- <section>
- <h3>Lower Level Datastore API</h3>
- <pre><code class="brush: objc;">
- SMQuery *query = [[SMQuery alloc] initWithSchema:@"todo"];
- [q where:@"age" isGreaterThan:25];
-
- [[[SMClient defaultClient] dataStore] performQuery:query
- onSuccess:^(NSArray *results) {
- // Handle success
- } onFailure:^(NSError *error) {
- // Handle error
- }
- ];
- </code></pre>
- </section>
-
+ <li class="big50 lineSpace">Platform for Mobile Backends.</li>
+ <li class="big50 lineSpace">Lowering barrier of entry.</li>
+ <li class="big50 lineSpace">Focus on your user experience.</li>
+ <li class="big50 lineSpace">Access to "big company" backend power.</li>
+ </ul>
</section>
<section>
- <h2>Relationships</h2>
- <img height=500px src="https://dl.dropbox.com/u/79464649/holdingHands.jpg" />
+ <h2>Let's Build HollaGram!</h2>
+ <img width="300px" src="https://dl.dropbox.com/u/79464649/holla.jpeg"/>
</section>
<section>
- <h2>User Authentication</h2>
- <section>
- <img src="http://dl.dropbox.com/u/77348001/calving_hobbes_password.gif" alt=""/>
- </section>
-
- <section>
- <h3>Login</h2>
- <pre><code class="brush: objc;">
- [[SMClient defaultClient] loginWithUsername:self.usernameField.text
- password:self.passwordField.text
- onSuccess:^(NSDictionary *results) {
- // Handle success
- } onFailure:^(NSError *error) {
- // Handle failure
- }];
- </code></pre>
- </section>
-
- <section>
- <h3>Check Login Status</h2>
- <pre><code class="brush: objc;">
- [[SMClient defaultClient] getLoggedInUserOnSuccess:^(NSDictionary *result) {
- self.statusLabel.text = [NSString stringWithFormat:@"Hello, %@",
- [result objectForKey:@"username"]];
- } onFailure:^(NSError *error) {
- NSLog(@"No user found");
- }];
- </code></pre>
- </section>
-
- <section>
- <h3>Logout</h2>
- <pre><code class="brush: objc;">
- [[SMClient defaultClient] logoutOnSuccess:^(NSDictionary *result) {
- // Handle success
- } onFailure:^(NSError *error) {
- // Handle error
- }];
- </code></pre>
- </section>
-
- <section>
- <h3>Password Management</h3>
- <ul>
- <li class="moreLineSpace big50">Forgotten Passwords</li>
- <li class="moreLineSpace big50">Reset Password</li>
- </ul>
-
- </section>
- </section>
- <!--
- <section>
- <h2>Security &rarr; OAuth 2.0</h2>
-
- <ul>
- <li>Industry Standard: OAuth 1.0/2.0</li>
- <li>Public/Private Keys identify your app's requests</li>
- <li>FB/Twitter: OAuth 2.0. Username/Password</li>
- <li>In current JS SDK for pre-trials</li>
- </ul>
-
- </section>
- -->
- <section>
- <h2>Access Controls</h2>
- <ul>
- <li class="moreLineSpace big50">Share objects to certain users.</li>
- <li class="moreLineSpace big50">Only authenticated users should be able to access certain data.</li>
- <li class="moreLineSpace big50">Limit visibility.</li>
- </ul>
- </section>
-
- <section>
- <h2>Push</h2>
- <pre><code class="brush: objc;">
- // In application:didFinishLaunchingWithOptions:
- // Assuming you declared the variable "SMPushClient *pushclient;"
- pushClient = [[SMPushClient alloc] initWithAPIVersion:@"0"
- publicKey:@"publicKey" privateKey:@"privateKey"];
-
- [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
- (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
- UIRemoteNotificationTypeSound)];
- </code></pre>
- <pre><code class="brush: objc; highlight: [11,12]">
- - (void)application:(UIApplication *)app
- didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
- {
- NSString *token = [[deviceToken description]
- stringByTrimmingCharactersInSet:[NSCharacterSet
- characterSetWithCharactersInString:@"<>"]];
-
- token = [[token componentsSeparatedByString:@" "]
- componentsJoinedByString:@""];
-
- [pushClient registerDeviceToken:token withUser:@"randomuser"
- onSuccess:createdSuccessBlock onFailure:createdFailureBlock];
- }
- </code></pre>
- </section>
- <section>
- <h2>Facebook and Twitter Authentication</h2>
- <ul>
- <li class="lineSpace">createUserWithFacebookToken:onSuccess:onFailure:</li>
- <li class="lineSpace">loginWithFacebookToken:onSuccess:onFailure:</li>
- <li class="lineSpace">updateFacebookStatusWithMessage:onSuccess:onFailure:</li>
- <li class="lineSpace">getLoggedInUserFacebookInfoWithOnSuccess:onFailure:</li>
- </ul>
- <br/>
- <br/>
- <ul>
- <li class="lineSpace">createUserWithTwitterToken:twitterSecret:onSuccess:onFailure:</li>
- <li class="lineSpace">loginWithTwitterToken:twitterSecret:onSuccess:onFailure:</li>
- <li class="lineSpace">updateTwitterStatusWithMessage:onSuccess:onFailure:</li>
- <li class="lineSpace">getLoggedInUserTwitterInfoOnSuccess:onFailure:</li>
- </ul>
- </section>
- <section>
-
<section>
<h2>Even more flexibility: Custom Code</h2>
- <ul>
- <li class="moreLineSpace big50">Java/Scala Server Side SDK.</li>
- <li class="moreLineSpace big50">Write Code - StackMob REST-ifies it.</li>
- <li class="moreLineSpace big50">iOS can execute your server code via REST API!</li>
- <li class="moreLineSpace big50">iOS receives your custom JSON response too.</li>
- </ul>
- </section>
-
- <section>
- <h2>Call Custom Code from iOS App!</h2>
- <pre><code class="brush: objc;">
- [[SMCustomCodeRequest *ccRequest = SMCustomCodeRequest alloc]
- initGetRequestWithMethod:@"hello_world" body:nil];
-
- [[SMClient defaultClient] performCustomCodeRequest:ccRequest
- onSuccess:^(NSURLRequest request, NSHTTPURLResponse response, id JSON) {
- // Returns a JSON body specified by the custom code method
- } onFailure:^(NSURLRequest request, NSHTTPURLResponse response, NSError *error, id JSON) {
- // Handle failure
- }
- ];
- </code></pre>
- </section>
-
- <section>
- <h2>Custom Code Example</h2>
-
-<pre><code class="brush: java">
+ <pre><code class="brush: java">
//Java
public class HelloWorldExample implements CustomCodeMethod {
@@ -777,72 +310,39 @@
@Override
public ResponseToProcess execute(...) {
- //Do fancy server side things
+ // Do fancy server side things
- Map&lt;String, String&gt; json =
- new HashMap&lt;String, String&gt;();
- json.put("msg", "hello world!");
- return new ResponseToProcess(..., json);
}
}
-</code></pre>
- </section>
-
- <section>
- <h2>Defines your REST endpoint</h2>
- <p><code>http://api.mob1.stackmob.com/hello_world</code></p>
-<pre><code class="brush: java; highlight: [6]">
-//Java
-public class HelloWorldExample implements CustomCodeMethod {
-
- @Override
- public String getMethodName() {
- return "hello_world";
- }
-
- ...
-}
-</code></pre>
+</code></pre>
</section>
<section>
- <h2>Defines your return JSON</h2>
- <p><code>{ msg: "hello world!" }</code></p>
-<pre><code class="brush: java; highlight: [11]">
-//Java
-public class HelloWorldExample implements CustomCodeMethod {
- ...
- @Override
- public ResponseToProcess execute(...) {
-
- //Do fancy server side things
-
- Map&lt;String, String&gt; json =
- new HashMap&lt;String, String&gt;();
- json.put("msg", "hello world!");
- return new ResponseToProcess(..., json);
- }
-}
-</code></pre>
- </section>
+ <h2>Call Custom Code from iOS App!</h2>
+ <pre><code class="brush: objc;">
+ [[SMCustomCodeRequest *ccRequest = SMCustomCodeRequest alloc]
+ initGetRequestWithMethod:@"hello_world" body:nil];
+
+ [[SMClient defaultClient] performCustomCodeRequest:ccRequest
+ onSuccess:^(NSURLRequest request, NSHTTPURLResponse response, id JSON) {
+ // Returns a JSON body specified by the custom code method
+ } onFailure:^(NSURLRequest request, NSHTTPURLResponse response, NSError *error, id JSON) {
+ // Handle failure
+ }
+ ];
+ </code></pre>
+ </section>
</section>
<section>
<h2>Development &amp; Production Environments</h2>
- <ul>
- <li class="moreLineSpace big50">Different databases.</li>
- <li class="moreLineSpace big50">Only deploy when you're ready!</li>
- <li class="moreLineSpace big50">Easy rollout/rollback.</li>
- </ul>
+ <img width="500px" src="https://dl.dropbox.com/u/79464649/deployToProd.png" />
</section>
<section>
<h2>API Versions</h2>
- <ul>
- <li class="moreLineSpace big50">Backwards support old clients.</li>
- <li class="moreLineSpace big50">Concurrently run different versions of your custom code/schemas.</li>
- </ul>
+ <img width="500px" src="https://dl.dropbox.com/u/79464649/apiVersions.png" />
</section>
<section>
@@ -854,49 +354,13 @@
</ul>
</section>
+ <!--
<section>
<h2>The future of the iOS SDK</h2>
<img height=500px src="https://dl.dropbox.com/u/79464649/future.jpg" />
</section>
-
- <section>
- <h2>Open Sourced SDKs</h2>
-
- <ul>
- <li class="moreLineSpace big50">iOS</li>
- <li class="moreLineSpace big50">Android</li>
- <li class="moreLineSpace big50">Javascript</li>
- <li class="moreLineSpace big50">Download them today!</li>
- </ul>
- </section>
-
- <section>
- <h2>Adding a backend with StackMob</h2>
- <ul>
- <li class="moreLineSpace big50">Simple.</li>
- <li class="moreLineSpace big50">Seamless.</li>
- <li class="moreLineSpace big50">Flexible.</li>
- <li class="moreLineSpace big50">Powerful.</li>
- <li class="moreLineSpace big50">Free &rarr; Grow.</li>
- </ul>
- </section>
-
- <section>
- <h2>Backend Services</h2>
- <ul>
- <li class="lineSpace">User Authentication</li>
- <li class="lineSpace">Datastore</li>
- <li class="lineSpace">Security</li>
- <li class="lineSpace">GeoSpatial</li>
- <li class="lineSpace">Push</li>
- <li class="lineSpace">Hosting</li>
- <li class="lineSpace">Social Integration</li>
- <li class="lineSpace">Custom Server Side Code</li>
- <li class="lineSpace">Analytics</li>
- <li class="lineSpace">...</li>
- </ul>
- </section>
+ -->
<section>
<h2>Thank you!</h2>
@@ -905,26 +369,22 @@
</section>
<section>
- <h2>Try it out!</h2>
+ <p class="big50">Slides @ <a class=" big50" href="http://bit.ly/OKbXHM">http://bit.ly/OKbXHM</a></p>
+ <br/>
+ <h3>Try out the demo and StackMob!</h3>
+ <a class="lineSpace big50" href="https://github.com/msv/hollagram-ios">https://github.com/msv/hollagram-ios</a>
+ <br/>
+ <br/>
<a class="lineSpace big50" href="https://developer.stackmob.com">https://developer.stackmob.com</a>
<br/>
<br/>
- <h2>Get the Slides</h2>
- <a class="lineSpace big50" href="http://bit.ly/OKbXHM">http://bit.ly/OKbXHM</a>
+ <h3>Free Core Data eBook!</h3>
+ <a class="lineSpace big50" href="http://go.stackmob.com/learncoredata.html">http://go.stackmob.com/learncoredata.html</a>
+ <br/>
+ <br/>
+ <p class="lineSpace">Matt Vaznaian | matt@stackmob.com | @_mattvaz</p>
</section>
-
- <section>
- <h2>Acknowledgements</h2>
- <ul>
- <li>Reveal.js and Styles - Hakim El Hattab </li>
- <li>MySQL, Oracle, AWS, Dell, Intel, Google App Engine, Heroku - Google Images</li>
- <li>Head In Hands, Awesome Note, Dr. Evil, Holding Hands, Future - Google Images</li>
- <li>Cookie Monster - Sesame Street</li>
- <li>Calvin &amp; Hobbes - Bill Watterson</li>
-
- </ul>
- </section>
</div>
View
687 ios/iOS_Meetup.html
@@ -1,687 +0,0 @@
-<html>
- <head>
- <title>StackMob - A Mobile Development Platform for Backend Solutions</title>
- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
- <script type="text/javascript" src="http://static.stackmob.com/js/json2-min.js"></script>
- <script type="text/javascript" src="http://static.stackmob.com/js/underscore-1.3.3-min.js"></script>
- <script type="text/javascript" src="http://static.stackmob.com/js/backbone-0.9.2-min.js"></script>
- <script type="text/javascript" src="http://static.stackmob.com/js/stackmob-js-0.2.1-min.js"></script>
- <script type="text/javascript" src="http://static.stackmob.com/resources/js/jsonFormatter-0.1.0-min.js"></script>
- <script type="text/javascript" src="stackmob-debug.js"></script>
-
- <!-- Include required JS files -->
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shCore.js"></script>
-
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushJScript.js"></script>
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushXml.js"></script>
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushJava.js"></script>
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushCpp.js"></script>
- <script type="text/javascript" src="../syntaxhighlighter/scripts/shBrushObjC.js"></script>
-
- <link href="../syntaxhighlighter/styles/shCoreMidnight.css" rel="stylesheet" type="text/css" />
- <link href="../syntaxhighlighter/styles/shThemeMidnight.css" rel="stylesheet" type="text/css" />
-
- <style type="text/css">
- .syntaxhighlighter {
- margin: 0px !important; padding-top: 15px; padding-bottom: 15px;
- border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px;
-
- }
- </style>
-
- <script type="text/javascript">
- StackMob.init({
- appName: 'javascript',
- clientSubdomain: 'stackmob',
- apiVersion: 0
- });
-
- var Todo = StackMob.Model.extend({
- schemaName: 'todo'
- });
-
- var Todos = StackMob.Collection.extend({
- model: Todo
- });
-
- $(document).ready(function() {
- SyntaxHighlighter.config.tagName = 'code';
- SyntaxHighlighter.config.toolbar = false;
- SyntaxHighlighter.all();
-
- Reveal.addEventListener('stampede', function() {
- $('#stampede').attr('src', 'http://dl.dropbox.com/u/77348001/stampede.gif');
- });
- });
- </script>
-
- <link rel="stylesheet" href="../reveal.js/css/reset.css">
- <link rel="stylesheet" href="../reveal.js/css/main.css">
- <style type="text/css" media="screen">
- .button, .button a
-{
- background: #98be47;
- background: linear-gradient(top, #a8cf43, #98be47);
- background: -moz-linear-gradient(top, #a8cf43, #98be47);
- background: -ms-linear-gradient(top, #a8cf43, #98be47);
- background: -o-linear-gradient(top, #a8cf43, #98be47);
- background: -webkit-linear-gradient(top, #a8cf43, #98be47);
- border: 1px solid #8cac42;
- border-bottom-color: #7b9b36;
- border-radius: 4px;
- border-top-color: #94b146;
- box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
- color: #fff !important;
- cursor: pointer;
- font-family: "Helvetica Neue", Arial, sans-serif;
- font-size: 26px;
- font-weight: bold;
- moz-border-radius: 4px;
- moz-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
- ms-border-radius: 4px;
- ms-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
- o-border-radius: 4px;
- o-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
- padding: 6px 14px;
- text-decoration: none;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, .4);
- webkit-border-radius: 4px;
- webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, .2), inset 0 1px 0 rgba(255, 255, 255, .5);
-}
-.button:hover, .button a:hover
-{
- background: #67a215;
- background: linear-gradient(top, #9dbf46, #67a215);
- background: -moz-linear-gradient(top, #9dbf46, #67a215);
- background: -ms-linear-gradient(top, #9dbf46, #67a215);
- background: -o-linear-gradient(top, #9dbf46, #67a215);
- background: -webkit-linear-gradient(top, #9dbf46, #67a215);
- border: 1px solid #699631;
- border-bottom-color: #457119;
- border-top-color: #6d9e34;
- color: rgba(250, 250, 250, .96);
- text-decoration: none;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
-}
-.button:active, .button a:active
-{
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
- moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
- ms-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
- o-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
- padding: 4px 14px 7px;
- webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
-}
-.button.blue, .button.blue a
-{
- background: #6bbad7;
- background: linear-gradient(top, #76cced, #6bbad7);
- background: -moz-linear-gradient(top, #76cced, #6bbad7);
- background: -ms-linear-gradient(top, #76cced, #6bbad7);
- background: -o-linear-gradient(top, #76cced, #6bbad7);
- background: -webkit-linear-gradient(top, #76cced, #6bbad7);
- border: 1px solid #4ca8ca;
- border-bottom-color: #4c9bb9;
- border-top-color: #4cb2da;
-}
-.button.blue:hover, .button.blue a:hover
-{
- background: #2c9cc6;
- background: linear-gradient(top, #3cb7e5, #2c9cc6);
- background: -moz-linear-gradient(top, #3cb7e5, #2c9cc6);
- background: -ms-linear-gradient(top, #3cb7e5, #2c9cc6);
- background: -o-linear-gradient(top, #3cb7e5, #2c9cc6);
- background: -webkit-linear-gradient(top, #3cb7e5, #2c9cc6);
- border: 1px solid #0083b4;
- border-bottom-color: #00709b;
- border-top-color: #0092ca;
-}
-
-#stackmoblogo {
- position: fixed;
- top: 20px;
- left: 20px;
-}
-
-.line { font-size: 50px ! important; }
-.logo { width: 400px; }
-.pic { height: 300px; }
-.big35 { font-size: 35px;}
-.big50 { font-size: 50px;}
-.big75 { font-size: 75px;}
-.big100 { font-size: 100px;}
-.top15 { margin-top: 15px; }
-.top25 { margin-top: 25px; }
-.top35 { margin-top: 35px; }
-.top50 { margin-top: 50px; }
-.top75 { margin-top: 75px; }
-.top100 { margin-top: 100px; }
-.lineSpace { line-height: 1.4em }
-.moreLineSpace { line-height: 2.0em }
- </style>
-
- </head>
- <body>
- <div id="stackmoblogo"><img src="../images/stackmob_logo.png"/></div>
- <div id="reveal">
- <div class="state-background"></div>
-
- <div class="slides">
- <section>
- <h2>StackMob<br/>A Mobile Backend Platform</h2>
- <!-- <h3 class="inverted">StackMob &amp; Objective-C</h3> -->
- <!-- <p><span style="font-size: 24px;">(uses Backbone.js)</span></p> -->
- <p style="margin-top: 100px;">
- <p>Matt Vaznaian | <a href="http://www.twitter.com/mvaznaian" target="_blank">@_mattvaz</a></p>
- <p><a href="http://www.stackmob.com" target="_blank">stackmob.com</a> | <a href="http://www.twitter.com/stackmob">@StackMob</a></p>
- </p>
- </section>
- <!--
- <section>
- <h2>A Brief History of Building your backend</h2>
-
- <section>
- </section>
-
- <section>
- <h3>Database</h3>
- <img src="https://dl.dropbox.com/u/79464649/oracle.jpg" />
- <img src="https://dl.dropbox.com/u/79464649/mysql-big.gif" />
- </section>
-
- <section>
- <h3>Hardware</h3>
- <img src="https://dl.dropbox.com/u/79464649/300px-Dell_Logo.svg_1.png" />
- <img src="https://dl.dropbox.com/u/79464649/intel-logo-300x198.jpg" />
- </section>
-
- <section>
- <h3>Cloud Store</h3>
- <img width=350px src="https://dl.dropbox.com/u/79464649/amazon.png" />
- <img width=300px src="https://dl.dropbox.com/u/79464649/iCloud.png" />
- </section>
-
- <section>
- <h3>Software Layer</h3>
- <img src="https://dl.dropbox.com/u/79464649/heroku.jpg" />
- <img src="https://dl.dropbox.com/u/79464649/appengine-logo.png" />
- </section>
-
- <section>
- <h3>Platform</h3>
- <p><img width=600px src="../images/stackmob_fulllogo_white.png"/></a></p>
- </section>
-
- </section>
- -->
-
- <!--
- <section>
- <h2>StackMob: Who uses us?</h2>
-
- <p class="big50 lineSpace">We've powered apps:</p>
- <ul>
- <li class="big50 lineSpace">Featured in the AppStore</li>
- <li class="big50 lineSpace">Top 20 in the AppStore</li>
- <li class="big50 lineSpace">TechCrunch Disrupt</li>
- <li class="big50 lineSpace">SXSW</li>
- <li class="big50 lineSpace">Won Startup Weekend</li>
- <li class="big50 lineSpace">Atari</li>
- </ul>
- <p class="big50 lineSpace">Games, Enterprise Apps, Social... </p>
- </section>
- -->
- <section>
- <h2>The First App You Ever Built</h2>
- <p>
- <img width="300px" src="https://dl.dropbox.com/u/79464649/helloWorld.png"/>
- </p>
- </section>
-
- <section>
- <h2>NSUserDefaults</h2>
- <p>
- <img width="300px" src="https://dl.dropbox.com/u/79464649/helloMatt.png" />
- </p>
- </section>
-
- <section>
- <h2>Core Data</h2>
- <p>
- <img width="600px" src="https://dl.dropbox.com/u/79464649/core-data-model.png" />
- </p>
- </section>
-
- <section>
- <h2>Your New App Idea</h2>
- <img width="200px" src="https://dl.dropbox.com/u/79464649/databases.jpeg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/lock.jpeg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/geo.jpg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/facebooksm.jpg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/twittersm.jpg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/email.jpeg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/s3.jpg" />
- <img width="200px" src="https://dl.dropbox.com/u/79464649/scaling.jpeg" />
-
-
- </section>
-
- <section>
- <h2>You could build it yourself</h2>
-
- <img width="600px" src="https://dl.dropbox.com/u/79464649/databaseCenter.jpg" />
- </section>
-
- <section>
- <h2>Or...focus on your user experience!</h2>
-
- <img src="https://dl.dropbox.com/u/79464649/awesome_note.png" />
- </section>
-
- <section>
- <h2>StackMob To The Rescue</h2>
-
- <ul>
- <li class="big50 lineSpace">Platform for Mobile Backends.</li>
- <li class="big50 lineSpace">Lowering barrier of entry.</li>
- <li class="big50 lineSpace">Focus on your user experience.</li>
- <li class="big50 lineSpace">Access to "big company" backend power.</li>
- </ul>
- </section>
-
- <section>
- <h2>Let's Build HollaGram!</h2>
- <img width="300px" src="https://dl.dropbox.com/u/79464649/holla.jpeg"/>
- </section>
-
- <section>
-
- <section>
- <h2>Even more flexibility: Custom Code</h2>
- <pre><code class="brush: java">
-//Java
-public class HelloWorldExample implements CustomCodeMethod {
-
- @Override
- public String getMethodName() {
- return "hello_world";
- }
-
- @Override
- public ResponseToProcess execute(...) {
-
- // Do fancy server side things
-
- }
-}
-</code></pre>
- </section>
-
- <section>
- <h2>Call Custom Code from iOS App!</h2>
- <pre><code class="brush: objc;">
- [[SMCustomCodeRequest *ccRequest = SMCustomCodeRequest alloc]
- initGetRequestWithMethod:@"hello_world" body:nil];
-
- [[SMClient defaultClient] performCustomCodeRequest:ccRequest
- onSuccess:^(NSURLRequest request, NSHTTPURLResponse response, id JSON) {
- // Returns a JSON body specified by the custom code method
- } onFailure:^(NSURLRequest request, NSHTTPURLResponse response, NSError *error, id JSON) {