Lessons from developing a Client Server Iphone app

  • 19,094 views
Uploaded on

I launched an iphone app (Discounts For Me). The app downloads data from a server. I share some of the lessons learned while building the app and building the server back end in ruby on …

I launched an iphone app (Discounts For Me). The app downloads data from a server. I share some of the lessons learned while building the app and building the server back end in ruby on rails

http://discountsforme.net/

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • updated presentations : http://sujee.net/tech/articles/iphone-client-server-presentations.php
    Are you sure you want to
    Your message goes here
  • Author : Sujee Maniyam (http://sujee.net)
    Iphone app : http://discountsforme.net/

    please leave comments here : http://sujee.net/blog/tech/tech-lessons-from-building-a-client-server-iphone-app.html
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
19,094
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
290
Comments
2
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Lessons from developing anIphone App + Server backend
    Sujee Maniyam
    s@sujee.net
    http://sujee.net
    http://DiscountsForMe.net
    Aug 2009
  • 2. Target Audience
    Iphone app developers
    Server backend developers for mobile apps
    Expert level: Beginner - Intermediate
  • 3. My Background
    Developer (enterprise, web)
    Java / Php / Ruby
    First iphone/mobile app
  • 4. App: DiscountsForMe
    Shows member benefits
    Based on location
    V1.0 in app store
    Memberships:
    Public radio (KQED)
    Bank of America card
    AAA, AARP
    More…
  • 5.
  • 6. Architecture
    Server (DiscountsForMe.net) serves data
    Server is Rails app
    Iphone app talks to the server
    <Insert usual SERVER ---- INTERNET CLOUD ---- IPHONEpicture here>
  • 7. Agenda
    Connectivity
    Data format
    Secure Data trasnfer
    UDIDs & Keys
    Controlling app from server
  • 8. Connectivity : Simple Start
    App makes three server calls
    ping()
    get_memberships()
    get_discounts(my_location, my_memberships)
    Simulator
    Iphone over Wi-fi
    Iphone over 3G
    LAG-TIME is a problem
  • 9. Connectivity : Minimize Lag Time
    Noticeable lag time over 3G/Edge
    Reducing lag time
    Condense network calls (especially if the user is waiting for data)
    Download in background
    So
    Get_memberships()
    Get_discounts(my_location, my_memberships)
    get_memberships_and_discounts(loc, mymems)
  • 10. 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 )
  • 11. Connectivity Test
    Quick Ping
    Which is faster?
    httpS://www.DiscountsForMe.net/ping
    http://www.google.com
    SSL always takes longer to establish connection
    Use faster sites
    Another snippet from Erica Sadun’s book(to be verified)
  • 12. Talking to Server : Format
    Two choices : XML, JSON
    JSON smaller size than XML (50% less)
    Json : use TouchJSON library http://code.google.com/p/touchcode/wiki/TouchJSON
    XML : NSXML(sdk) / TouchXML / KissXMLhttp://www.71squared.co.uk/2009/05/processing-xml-on-the-iphone/
  • 13. Agenda
    Connectivity
    Data format
    Secure Data transfer
    UDIDs, Keys, analytics
    Controlling app from server
  • 14. 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
    httpS
  • 15. 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/
  • 16. Verify SSL Cert…
  • 17. Talking to Server : POST req
    NSMutableURLRequest *request = [NSMutableURLRequestrequestWithURL:url];
    [request setHTTPMethod:@"POST"];
    NSMutableString *postString = [NSMutableString string];
    [postStringappendFormat:@"%@=%@&", key, value];
    NSString *postString2 = [postString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:[postString2 dataUsingEncoding:NSUTF8StringEncoding]];
    NSURLResponse *response = nil;
    NSError *error = nil;
    NSData *data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:&responseerror:&error];
  • 18. Talking to Server : Local Server
    #ifdef DEBUG// dev
    #define MEMBER_SERVER @”http://localhost:3000”
    #else// production
    #define MEMBER_SERVER @”https://discountsforme.net”
    #endif
    - And define ‘DEBUG’ in build configurations
  • 19. Talking to Server : Dedicated Class
    • Don’t do URL connections all over the code. Have a class do it
    • 20. Easy to debug
    • 21. Use named methods (getDiscounts Vs connectToURL)
    @interface ServerConnection : NSObject {
    }
    + (BOOL) testConnectivity;
    + (BOOL) isConnected;
    + (NSArray *) getMemberships;
    + (NSArray *) getDiscounts:(NSDictionary *) params;
    @end
  • 22. Agenda
    Connectivity
    Data format
    Secure Data transfer
    UDIDs, Keys, multiple versions, analytics
    Controlling app from server
  • 23. What do I send to the server?
    get_memberships()
    No parameters?...
    Think about including
    UDID (device id)
    And a Key (compiled within the app)
    http://discountsforme.net/iphone/get_memberships
    http://discountsforme.net/iphone/get_memberships?udid=xxxx&key=yyyy
  • 24. Server Side : Unique Device ID
    Each mobile device has a uniq ID, etched in hardware (just like MAC address)
    Your app can send UDID with each request
    Of course : encrypt it or via SSL
    Very useful for metrics on app usage
    How many unique devices have the app
    Access patterns (repeat uses)
    Easy account creation (no signup)
  • 25. Server side : access keys
    Start using ‘access keys’ from day-1
    Sample key = “iphone_v1.0_xklajdfoi2” (human readable + hard to guess)
    Each request to server must have a valid key
    Easy to control client access
    Prevent scraping, DOS ..etc
    Monitoring (what versions are being used)
    Support multiple versions, easy upgrade
  • 26. 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…)
  • 27. Supporting multiple clients…
  • 28. 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”);}
  • 29. 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]"}
  • 30. Server side : Metrics : Logs
    Log every thing to database, don’t rely on logfiles
    This gives you pretty good metrics on your app usage
    On Rails, use around_filteraround_filter :log_access, :only => [:get_discounts, :get_memberships]
    Thirdparty metrics : FLURRY, PinchMedia…
  • 31. Server side : logging in Rails
    def log_access
    start_time = Time.now
    yield
    end_time = Time.now
    elapsed = ((end_time - start_time)*1000.0).to_int
    begin # b/c we don’t want to error during logging
    alog = MemberAccessLog.new
    alog.client_type_id = client_type_id
    alog.session = session.session_id
    ….
    alog.save!
    rescue
    end
    End
  • 32. Logging & Scalability
    If all your requests are READ-ONLY (from db) it is very easy to scale
    Load balancer can route requests to any server
    Database can be replicated easily
    Write-bound apps are little tricky to scale
  • 33. Agenda
    Connectivity
    Data format
    Secure Data transfer
    UDIDs, Keys, analytics
    Controlling app from server
  • 34. Controlling app behavior from Server
  • 35. 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
  • 36. Control…
    One example: Choosing if you are going to show ads?
    show_ads : {none | admob | tapjoy}
  • 37. 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 (for testing, scaling)
  • 38. Thanks!
    Sujee Maniyam
    s@sujee.net
    http://sujee.net
    http://DiscountsForMe.net
    Questions?