; iphone-server-v3-sf - Lessons from developing an Iphone App +
Documents
Resources
Learning Center
Upload
Plans & pricing Sign in
Sign Out
Your Federal Quarterly Tax Payments are due April 15th Get Help Now >>

iphone-server-v3-sf - Lessons from developing an Iphone App +

VIEWS: 19 PAGES: 57

  • pg 1
									  Lessons from developing an
 Iphone 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 ---- IPHONE
    picture 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 network
  over WIFI
• Run local server
  on laptop
• Iphone + Simulator
  can 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)
•    smaller size than
    JSON                  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 / KissXML
    http://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 properly
  http://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&k
  ey=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 Controller
  class MyController
   around_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 < ApplicationController
       filter_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 controller
  Class 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-servers
  by Ramin Firoozye
• Restful web services
Thanks!
• Sujee Maniyam
   – hello@sujee.net
   – http://sujee.net
• http://DiscountsForMe.net




• Questions?

								
To top