Iphone client-server app with Rails backend (v3)

57
Lessons from developing an Iphone App + Server backend Sujee Maniyam [email protected] http://sujee.net http://DiscountsForMe.net Feb 2010

description

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

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

Page 1: Iphone client-server app with Rails backend (v3)

Lessons from developing anIphone App + Server backend

Sujee [email protected]://sujee.nethttp://DiscountsForMe.netFeb 2010

Page 2: Iphone client-server app with Rails backend (v3)

Quiz

• PRIZE!

• Where was this picture taken?

Page 3: Iphone client-server app with Rails backend (v3)
Page 4: Iphone client-server app with Rails backend (v3)

My Background

• Developer (enterprise, web)• Java / Php / Ruby / obj-C• First iphone app (Apr 2009)

Page 5: Iphone client-server app with Rails backend (v3)

Target Audience

• Iphone app developers• Server backend developers

for mobile apps• Expert level:

Beginner - Intermediate

Page 6: Iphone client-server app with Rails backend (v3)

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

Page 7: Iphone client-server app with Rails backend (v3)

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…)

Page 8: Iphone client-server app with Rails backend (v3)

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…

Page 9: Iphone client-server app with Rails backend (v3)

Architecture

• Server (DiscountsForMe.net) serves data• Server is Rails app• Iphone app talks to the server• <Insert usual

SERVER ---- INTERNET CLOUD ---- IPHONEpicture here>

Page 10: Iphone client-server app with Rails backend (v3)

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

Page 11: Iphone client-server app with Rails backend (v3)

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

Page 12: Iphone client-server app with Rails backend (v3)

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()

Page 13: Iphone client-server app with Rails backend (v3)

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 )

Page 14: Iphone client-server app with Rails backend (v3)

Network setup – WIFI

• Home networkover WIFI

• Run local serveron laptop

• Iphone + Simulatorcan connect just fine

Page 15: Iphone client-server app with Rails backend (v3)

Setup for 3G

Page 16: Iphone client-server app with Rails backend (v3)

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/

Page 17: Iphone client-server app with Rails backend (v3)

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

Page 18: Iphone client-server app with Rails backend (v3)

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

Page 19: Iphone client-server app with Rails backend (v3)

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

Page 20: Iphone client-server app with Rails backend (v3)

Agenda

• Connectivity• Data format• Secure Data transfer• UDIDs, Keys, analytics• Controlling app from server

Page 21: Iphone client-server app with Rails backend (v3)

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

Page 22: Iphone client-server app with Rails backend (v3)

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/

Page 23: Iphone client-server app with Rails backend (v3)
Page 24: Iphone client-server app with Rails backend (v3)

Verify SSL Cert…

Page 25: Iphone client-server app with Rails backend (v3)

Break & Quiz

Page 26: Iphone client-server app with Rails backend (v3)

Agenda

• Connectivity• Data format• Secure Data transfer• UDIDs, Keys, multiple versions, analytics• Controlling app from server

Page 27: Iphone client-server app with Rails backend (v3)

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?

Page 28: Iphone client-server app with Rails backend (v3)

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)

Page 29: Iphone client-server app with Rails backend (v3)

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)

Page 30: Iphone client-server app with Rails backend (v3)

Metrics

• Client Side metrics• Server side metrics

Page 31: Iphone client-server app with Rails backend (v3)

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)

Page 32: Iphone client-server app with Rails backend (v3)

Metrics : Client Side

Page 33: Iphone client-server app with Rails backend (v3)

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

Page 34: Iphone client-server app with Rails backend (v3)

Sample Server Side log data

• Device_id : iphone, android, web, • Location• Ip_address• Response_time• Response_data_size• Client_key• Created_at• Updated_at

Page 35: Iphone client-server app with Rails backend (v3)

Server Side Metric : Time To Serve

• Want to measure the time spent on each request

• use around_filter in Controllerclass MyController

around_filter :log_access, :only => [:get_A]

Page 36: Iphone client-server app with Rails backend (v3)

Response Time …

def log_access start_time = Time.now yield end_time = Time.now elapsed = ((end_time - start_time)*1000.0).to_int

End

Page 37: Iphone client-server app with Rails backend (v3)

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.lengthEnd

Page 38: Iphone client-server app with Rails backend (v3)

Response Time Chart

Time (ms)

Page 39: Iphone client-server app with Rails backend (v3)

Response Size Chart

• Response size (kbytes)

Page 40: Iphone client-server app with Rails backend (v3)

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

Page 41: Iphone client-server app with Rails backend (v3)

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"]

Page 42: Iphone client-server app with Rails backend (v3)

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 APIif (is_v2_or_later(key)){ do something }else {do some thing else}

• This can get convoluted (see next page…)

Page 43: Iphone client-server app with Rails backend (v3)

Supporting multiple clients…

Page 44: Iphone client-server app with Rails backend (v3)

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”);}

Page 45: Iphone client-server app with Rails backend (v3)

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]"}

Page 46: Iphone client-server app with Rails backend (v3)

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

Page 47: Iphone client-server app with Rails backend (v3)

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)

endend

Page 48: Iphone client-server app with Rails backend (v3)

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 endend

Page 49: Iphone client-server app with Rails backend (v3)

Controlling app behavior from Server

Page 50: Iphone client-server app with Rails backend (v3)

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

Page 51: Iphone client-server app with Rails backend (v3)

Control…

• One example: should display ads?– show_ads : {none | admob | tapjoy}

• Alert Messages:– “try our new version that has cool feature XYZ”

Page 52: Iphone client-server app with Rails backend (v3)

Server Logistics

• Choosing a hosting plan• Deploy• monitoring

Page 53: Iphone client-server app with Rails backend (v3)

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)

Page 54: Iphone client-server app with Rails backend (v3)

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

Page 55: Iphone client-server app with Rails backend (v3)

Monitoring

• So you know when your server is down• Pingdom / CloudKick

Page 56: Iphone client-server app with Rails backend (v3)

Other Resources

• http://www.slideshare.net/raminf/iphone-backend-servers

by Ramin Firoozye• Restful web services

Page 57: Iphone client-server app with Rails backend (v3)

Thanks!

• Sujee Maniyam– [email protected]– http://sujee.net

• http://DiscountsForMe.net

• Questions?