Upgrade to Pro — share decks privately, control downloads, hide ads and more …

App & Service

App & Service

Ben Ragheb talked about two techniques he combined to implement a photo upload feature in his iOS app: (1) WebView/UIWebView JavaScript tricks, and (2) using Amazon Web Services.


May 09, 2013

More Decks by CocoaHeadsNYC

Other Decks in Programming


  1. App & Service Benjamin Ragheb CocoaHeads, New York City 9

    May 2013
  2. In cloud computing the people are served by two separate,

    yet equally important parts. The applications which interact with the users and the services which process their data. These are their stories.
  3. None
  4. Make Setup Easier • User snaps photo of blank log

    sheet • A sophisticated neural network (a.k.a. “Mike”) interprets photo • Send email to user when we’re done
  5. Constraints • Will anybody use it? • I hate writing

    web services
  6. To the Cloud! Amazon S3 (obviously)

  7. None
  8. Amazon SNS • You create a topic • Use HTTP

    to publish something to the topic • Amazon forwards the something to the topic’s subscribers
  9. Amazon SNS • Message is up to 64KB of whatever

    you like • Can forward to email, text message, HTTP, or SQS
  10. Separation of Concerns • App doesn’t need to know where

    message is going • Amazon keeps track of subscriptions • Official Objective-C SDK available • I can procrastinate! • I hate writing web services
  11. Workflow • Read instructions • Take photo • Answer questions

    • Submit to service • Photo to S3 • Metadata to SNS
  12. Lingering Worry • AWS credentials baked into app • What

    if a malicious user extracts them? • New credentials requires App Store review • A token-vending machine is server-side code • I hate writing web services
  13. Let’s work on the app • Let’s use a web

    view to present instructions • Why not load content from the network? • Feature requires network access anyway • Now we can revise any time • “Out of Order”
  14. Buttons in HTML • Links that look like buttons •

    URL like “action:///takePhoto” • To disable feature, remove buttons
  15. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *URL =

    [request URL]; if ([[URL scheme] isEqualToString:@"action"]) { if ([[URL path] isEqualToString:@"/takePhoto"]) { [self takePhoto:nil]; return NO; } else if ([[URL path] isEqualToString:@"/choosePhoto"]) { [self choosePhoto:nil]; return NO; } } if (navigationType == UIWebViewNavigationTypeLinkClicked) { [[UIApplication sharedApplication] openURL:URL]; return NO; } return YES; }
  16. Serendipity • If I can transmit information to the user…

    • …surely I can transmit to my code • Use Javascript to embed metadata
  17. <script type="text/javascript"> var access = { key: 'AKIAJV3BLV6Z3Y7FKURQ', secret: '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',

    bucket: 'logbook-capture', topic: 'arn:aws:sns:us-east-1:693923277227:logbooks-topic' } var jpegQuality = 0.5; var facilityTypes = ["", "Commercial", "Healthcare", "Hotel", "Industrial/Manufacturing", "Maritime", "Multifamily Residential", "Power Plant/Generation", "University/School", "Warehouse", "Other"]; </script>
  18. • “document.body.id” to see if this is the page you

    want • “javascriptVariableName” to read a scalar value • “javascriptArrayName.join(‘\0’)” to read an array stringByEvaluatingJavaScriptFromString:
  19. - (void)webViewDidFinishLoad:(UIWebView *)webView { NSString *bodyID = [webView stringByEvaluatingJavaScriptFromString:@"document.body.id"]; if

    ([bodyID isEqualToString:@"start"]) { SGLogbookCaptureSession *session = [[SGLogbookCaptureSession alloc] init]; session.amazonAccessKey = [webView stringByEvaluatingJavaScriptFromString:@"access.key session.amazonSecretKey = [webView stringByEvaluatingJavaScriptFromString:@"access.sec session.amazonBucketName = [webView stringByEvaluatingJavaScriptFromString:@"access.bu session.amazonTopicARN = [webView stringByEvaluatingJavaScriptFromString:@"access.topi session.logbookImageQuality = [[webView stringByEvaluatingJavaScriptFromString:@"jpegQ NSString *facilityTypes = [webView stringByEvaluatingJavaScriptFromString:@"facilityTy session.facilityTypes = [facilityTypes componentsSeparatedByString:@"\0"]; SGAccountController *accountController = [SGAccountController sharedController]; if (![accountController isGuest]) { session.emailAddress = accountController.emailAddress; } self.session = session; } }
  20. Success • Lines of server code written: 0 • Token

    vending machine? Do it later! • Submission handler? Do it later! • I hate writing web services
  21. Executive Producer Dick Wolf

  22. Benjamin Ragheb Keep in touch! @benzado http://www.benzado.com ben@benzado.com