• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Iphone client-server app with Rails backend (v3)
 

Iphone client-server app with Rails backend (v3)

on

  • 24,641 views

Some of the lessons learned from building a client-server iphone app (DiscountsForMe)

Some of the lessons learned from building a client-server iphone app (DiscountsForMe)

This is version 3 of the talk, presented at SF Ruby Meetup on Feb 17, 2010

Statistics

Views

Total Views
24,641
Views on SlideShare
23,105
Embed Views
1,536

Actions

Likes
17
Downloads
279
Comments
4

12 Embeds 1,536

http://sujee.net 1228
http://www.slideshare.net 112
http://myscribd.wordpress.com 108
http://www.sujee.net 48
http://paper.li 13
http://www.linkedin.com 10
https://www.linkedin.com 7
http://redwatch.posterous.com 5
https://web.archive.org 2
http://zootool.com 1
http://twitter.com 1
http://sujee.local 1
More...

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

14 of 4 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • updated presentations : http://sujee.net/tech/articles/iphone-client-server-presentations.php
    Are you sure you want to
    Your message goes here
    Processing…
  • sujee, great presentation. tons of great tips.

    I am about to start writing my first iPhone/Rails app today.

    btw, you might want to check out Apigee (http://apigee.com/) for the server side analytics. It’s free and is super easy to set up. I am using it on my Rails APIs already.
    Are you sure you want to
    Your message goes here
    Processing…
  • From the presenter:

    Some of the comments I received during the talk:

    1) 'BluePill' was mentioned for monitoring

    2) If you are just building a mobile backend and don't need the web app, you might consider Sinatra or some thing similar.

    3) how to divide processing between client / server:
    off load as much processing to client/phone. This way your server doesn't become bogged when your app takes off.

    4) I mentioned logging vital stats (time taken to server requests ..etc) so you can easily spot trends.
    Also consider Hyperic for gathering stats. It has nice history / graphing features

    5) I use APache + Phusion for my site.
    Nginx is considered a better choice for 'slow clients' like mobile apps. It keeps a low memory profile, so you'll get more connections out of a server.
    Are you sure you want to
    Your message goes here
    Processing…
  • This is version 3 of the talk, presented at SF Ruby Meetup on Feb 17, 2010
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Iphone client-server app with Rails backend (v3) Iphone client-server app with Rails backend (v3) Presentation Transcript

    • Lessons from developing anIphone App + Server backend
      Sujee Maniyam
      hello@sujee.net
      http://sujee.net
      http://DiscountsForMe.net
      Feb 2010
    • Quiz
      PRIZE!
      Where was this picture taken?
    • My Background
      Developer (enterprise, web)
      Java / Php / Ruby / obj-C
      First iphone app (Apr 2009)
    • Target Audience
      Iphone app developers
      Server backend developers for mobile apps
      Expert level: Beginner - Intermediate
    • Why Client-Server Apps?
      Some apps run fine on the device disconnected (Tips calculator)
      “I think” majority of SMART apps in the future will have a server backend
      Some cool apps
      Amazon
      Yelp
      Red Laser
      Countless games
    • Server Backend gives you…
      A community (games, social interactions)
      Push Notification
      Heavy computational lifting (image recognition)
      Up-to date data (bar code scanners)
      ‘collective intelligence’ (most popular item today is…)
    • My App: DiscountsForMe
      Shows member benefits
      Based on location
      V2.0 in app store
      Memberships:
      Public radio (KQED, WHYY)
      Bank of America card
      AARP
      More…
    • Architecture
      Server (DiscountsForMe.net) serves data
      Server is Rails app
      Iphone app talks to the server
      <Insert usual SERVER ---- INTERNET CLOUD ---- IPHONEpicture here>
    • Web App / Mobile App ?
      What should server side code support?
      Are you adding mobile support for an existing web-app?
      Just mobile platform? (simpler ??)
      Hybrid (web + mobile)  more work
      DiscountsForMe is a hybrid app
    • 1) Connectivity : Simple Start
      First cut : App made three server calls at startup
      ping()
      Get_X()
      Get_Y()
      Simulator
      Iphone over Wi-fi
      Iphone over 3G
      LAG-TIME is a problem
    • Connectivity : Minimize Lag Time
      Noticeable lag time over 3G/Edge
      Reducing lag time
      Show cached data
      Download in background
      Condense network calls (especially if the user is waiting for data)
      So, condensed call becomes
      Get_X()
      Get_Y()
      get_X_Y()
    • Iphone Connectivity
      BIG LESSON 1 :
      Test on IPHONE (not just simulator)
      Test with WiFi OFF! (3G can be slow to connect, EDGE even worse)
      You may need to reorganize the logic to improve response time (I had to)
      LESSON 2
      Test in AirPlane Mode (all RADIOS off)(a frequent reason network apps are rejected )
    • Network setup – WIFI
      Home networkover WIFI
      Run local serveron laptop
      Iphone + Simulatorcan connect just fine
    • Setup for 3G
    • Network Setup for 3G
      Need a public IP
      Use a hosted server
      Or use your cable modem public-IP and have your router do port-forwarding
      DYNDNS : http://www.dyndns.com/
    • 2) Talking to Server : Format
      Choices : XML, JSON, other (csv, binary – protobuf/thift)
      JSON smaller size than XML (50% less)
      Json : use TouchJSON library http://code.google.com/p/touchcode/wiki/TouchJSON
      JSON String  Touch JsonNSDictionary (yay!)
      XML : NSXML(sdk) / TouchXML / KissXMLhttp://www.71squared.co.uk/2009/05/processing-xml-on-the-iphone/
      Rails makes it real easy to send Json/xml
      Some_obj.to_json
      Some_obj.to_xml
    • Keeping it small
      Trim objects
      No need to send all attributes
      Active records have extra attributes (created_at, updated_at ..etc)
      Example:
      # specify attributes to serialize
      obj.to_json(:only => [:name, :age])
      # combine other
      my_response = {}
      my_response[:book_name] = book.name
      my_response[:author_name] = book.author.name
      render(:json => my_response.to_json())
      - Compress (zip) response
    • GET vs POST
      iPhone SDK has a simple switch to control GET / POST
      What is the difference in Rails?
      Post requests have ‘authenticity token’ for cookie based sessions
      Use DB based sessions or turn off authenticity-protection
    • Agenda
      Connectivity
      Data format
      Secure Data transfer
      UDIDs, Keys, analytics
      Controlling app from server
    • Secure Data Transfer
      Plain HTTP is fine most of the time
      If you want to secure data
      Symmetric key encryption (shared ‘seckr3t’ key on Iphone app and server)
      Public-private key encryption (e.g. SSH) : private key on server, public key on iphone
      Enter : HTTPS
    • Secure data transfer : httpS
      SSL is ‘good enough’ for most of us
      Get a proper SSL certificate ($30). Self-signed certs don’t work by default
      Beware connection time is a little longer for httpS
      Verify your ssl certificate is installed properlyhttp://www.digicert.com/help/
    • Verify SSL Cert…
    • Break & Quiz
    • Agenda
      Connectivity
      Data format
      Secure Data transfer
      UDIDs, Keys, multiple versions, analytics
      Controlling app from server
    • What do I send to the server?
      Think about including
      UDID (device id)
      And a Key (compiled within the app)
      http://example.com/iphone/foo?udid=xxxx&key=yyyy
      Why?
    • Unique Device ID (UDID)
      Each iphone has a unique ID, etched in hardware (just like MAC address)
      Your app can send UDID with each request
      Uses
      metrics on app usage
      Easy account creation (no signup)
    • Identify a User (Device)
      UDID can help you ‘auto –create’ accounts on server
      Eg. High scores of games
      Allow users to create a custom user name later
      Beware of a user using multiple devices (multiple UDIDs)
    • Metrics
      Client Side metrics
      Server side metrics
    • Client Side Metrics
      Code embedded in your iphone app
      Usage, Users (new, repeat), session length
      Few companies (Flurry, Pinch Media ..etc)
      Pretty easy to integrate
      Nice dashboards
      Free! (mostly)
    • Metrics : Client Side
    • Server Side Metrics
      why?
      Some things are easily measured on server side
      ‘collective intelligence’
      Popular discounts
      Security audits
      Isolating an IP-address doing too many requests / scraping
      Easy to extract data / graphs ..etc
      Needs a bit of work on your side
    • Sample Server Side log data
      Device_id : iphone, android, web,
      Location
      Ip_address
      Response_time
      Response_data_size
      Client_key
      Created_at
      Updated_at
    • Server Side Metric : Time To Serve
      Want to measure the time spent on each request
      use around_filter in Controllerclass MyControlleraround_filter :log_access, :only => [:get_A]
    • Response Time …
      def log_access
      start_time = Time.now
      yield
      end_time = Time.now
      elapsed = ((end_time - start_time)*1000.0).to_int
      End
    • Server side Metric 2) Response Size
      def log_access
      start_time = Time.now
      yield
      end_time = Time.now
      elapsed = ((end_time - start_time)*1000.0).to_int
      response_data_size = response.body.length
      End
    • Response Time Chart
      Time (ms)
    • Response Size Chart
      Response size (kbytes)
    • Access keys
      Keys are random, ‘sekret’ strings compiled into the iphone app
      Sample key = “iphone_v1.0_xklajdfoi2” (human readable + ‘hard to guess’)
      Start using ‘access keys’ from day-1
      Each request to server must have a valid key
      Uses
      Easy to control client access (Prevent scraping, DOS ..etc)
      Monitoring (what versions are being used)
      Support multiple versions, easy upgrade
    • Access Keys
      In controller:
      @@keys = [ "iphone_v0.0_foobar” ,
      "iphone_v1.0_afajiu” ,
      "iphone_v2.0_fi98d”,
      "iphone_v2.0_plus_fsafa” ,
      "android_v1.0_fasjlkuo”
      ]
      @@keys_premium = ["iphone_v2.0_plus_fsfa"]
    • Supporting multiple versions
      May be supporting 2-3 client versions at a time (users don’t always run the latest)
      Keep old ‘API’ around, build-out new API if (is_v2_or_later(key)) { do something } else {do some thing else}
      This can get convoluted (see next page…)
    • Supporting multiple clients…
    • Supporting Multiple Clients…
      Have different controllers handle different client versions#define SERVER @”https://foo.com/iphone1”#define SERVER @”https://foo.com/iphone2”
      Make sure to avoid code duplication
      Plan-B : End-of-life
      If ( ! is_supported_version(key)){send_msg(“please upgrade”);}
    • Server side : keeping it secure
      Make sure ‘secret stuff’ doesn’t get logged in log-files
      In Rails : class Mobile::MobileController < ApplicationControllerfilter_parameter_logging [:key, :uid]
      end
      Output:
      Processing IphoneController#get_memberships_and_discounts (for 166.137.132.167 at 2009-07-02 16:07:41) [POST]
      Session ID: 126e5a73742f92f85c1158ea63fd960a
      Parameters: {"loc"=>"39.282440,-76.765693", "action"=>"get_memberships_and_discounts", "uid"=>”[FILTERED]", "controller"=>"mobile/iphone", "dist"=>"25", "mems"=>"", "key"=>"[FILTERED]"}
    • Example : Controllers
      MobileController
      IPhoneController < MobileController
      AndroidController < MobileController
      Most of the shared logic in ‘MobileController’
      Sample iPhone controllerClass IphoneController < MobileController def client_type_id 3 end end
    • Example …
      Class MobileController
      @@valid_keys = [……]
      def ping
      to_ret = {}
      begin
      validate
      to_ret[:status] = “OK”
      rescue
      to_ret[:error] = $1.message
      end
      render (:json => to_ret.to_json)
      end
      end
    • Example …
      Def validate
      #verify the key
      if (params[:key].blank?)
      raise DiscountsError, "dude, where is my key?"
      end
      if (params[:uid].blank?)
      raise DiscountsError, "dude, who are you?"
      end
      unless (@@valid_keys .has_key?(params[:key]))
      raise DiscountsError, "un supported version, please upgrade"
      end
      end
      end
    • Controlling app behavior from Server
    • Control …
      Apps changes are not easy to ‘get out’
      Approval process takes time
      Users may not upgrade to latest version
      Server changes are under your control and easy to deploy
      So build in control-switches in the app, that can be directed from server
    • Control…
      One example: should display ads?
      show_ads : {none | admob | tapjoy}
      Alert Messages:
      “try our new version that has cool feature XYZ”
    • Server Logistics
      Choosing a hosting plan
      Deploy
      monitoring
    • Hosting
      Shared hosting is fine, but others might swamp your DB, CPU ..etc
      If you can, get a VPS (Virtual Private Server)
      Plans start from $20 / month (SliceHost, Hosting-Rails ..etc)
      You have full ROOT access to the server (install packages, run CRON jobs ..etc)
      EC2 is great also (for testing, scaling)
    • Server : When to get it
      Don’t wait till TESTING phase!
      Get it from DAY-1, WEEK-1
      Can use DNS services like DYNDNS to test on your own workstation, during development
      Work on easy deploy scripts
      Capistrano
      Or rsync
    • Monitoring
      So you know when your server is down
      Pingdom / CloudKick
    • Other Resources
      http://www.slideshare.net/raminf/iphone-backend-serversby RaminFiroozye
      Restful web services
    • Thanks!
      Sujee Maniyam
      hello@sujee.net
      http://sujee.net
      http://DiscountsForMe.net
      Questions?