IOS

From Supernifty
Jump to: navigation, search

iPhone, XCode and OSX Development

Problem: Base SDK Missing

  • Project->Edit Project Settings - set Base SDK to Latest iOS.
  • Project->Edit Active Target - set Base SDK to Latest iOS.
  • Restart XCode

Native app with HTML UI

  • Use a UIWebView as a container for the HTML

Local Resources

- (void)loadView {
  NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
  NSData *data = [NSData dataWithContentsOfFile:path];
  [webView loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL fileURLWithPath:path]];
}
  • Setting the baseURL ensures other resources will also be loaded when the main HTML file loads in the webview.
  • Use an absolute URL to load remote URL.

Performance Tips

  • Use a single UIWebView
  • Build new views off screen and animate them in - see Dashcode for examples
  • If a Low Memory Notification is received, null JavaScript objects, and reinitialize them.

Authentication

  • No UI required: use https://username:password@www.site.com
  • To present a UI:
    • use a separate URL connection
    • connection:didReceiveAuthenticationChallenge
    • Store credentials with NSURLCredentialPersistenceForSession
    • UIWebView will use cached credentials

Executing JS from Objective-C

[webView stringByEvaluatingJavaScriptFromString:@"my_js()"];
  • JS should be in a separate file
  • JS should be copied, not compiled
  • Ensure the view has loaded (use webViewDidFinishLoad)

Executing Objective-C from JS

  • JS sets the location to a custom URL
native
function go_native() {
  window.location = "http://myapp/go_native";
}
  • Capture the load event
- (BOOL)webView:(UIWebView *)view shouldStartLoadWithRequest:(NSURLRequest *)req {
  if ( [[[req URL] host] isEqualToString:@"myapp"]) {
    NSString *cmd = [[[req URL] path] lastPathComponent];
    if ([cmd isEqualToString:@"go_native""]) {
      // do native stuff
    }
    return NO;
  }
}

Optimization

Reduce Image Count

  • Once an image is decoded it uses a lot of memory
  • Generate images in CSS
CSS Gradients
background: -webkit-gradient ( linear, left top, left 45%, from (#c3f7a5), to(white) );

means: type of gradient (linear/radial), start, end, colour start, colour end.

CSS Masks

-webkit-mask

analagous to background properties

e.g.

-webkit-mask-box-image: url(circle-mask.png) 100 75;

Instead of using circle-mask.png, a radial gradient or SVG image ( <circle...>) could be used, to eliminate that image.

CSS Reflections

-webkit-box-reflect <direction> <offset> <mask-box-image>

e.g.

-webkit-box-reflect below 5px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop( 0.7, transparent ), to(white));

CSS Transforms

  • translate, rotate, stretch or skew

e.g.

.item {
  -webkit-transform: rotate(180deg) scale(2.5) translateX(100px);
}

Also 3d transformations.

See http://developer.apple.com/safari - Poster Circle and Finger Tips for examples.

CSS Transitions

.item {
  -webkit-transform: scale(1) rotate(0deg);
  opacity: 0;
  -webkit-transition-property: -webkit-transform, opacity;
  -webkit-transition-duration: 1.3s, 2s;

}

.move {
  -webkit-transform: scale(1.25) rotate(180deg);
  opacity: 1;
}

function move(o) {

 o.className = ( o.className == "item" ) ? "item move" : "item";

}

  • Modify the linearity of the transition with -webkit-transition-timing-function
  • Delay the transition with -webkit-transition-delay

CSS Animations

  • Define the animation
@-webkit-keyframes 'fall' {
  from { -webkit-transform: translateY( -50px ); } /* start from above top */
  to { -webkit-transform: translateY( 600px ); } /* finish below bottom */
}
  • Add transformation
@-webkit-keyframes 'fade' {
 0% { opacity: 1; }
 75% { opacity: 1; }
 100% { opacity: 0; }
}
  • Apply to item
.leaf {
  -webkit-animation-name: 'fall', 'fade';
  -webkit-animation-duration: 10s, 10s;
  -webkit-animation-iteration-count: infinite, infinite;
  -webkit-animation-timing-function: linear, ease-in;
 }
  • Associated events: webkitAnimationStart, webkitAnimationIteration, webkitAnimationEnd
  • CSS transitions, animations will always be faster than JavaScript equivalent.

Buttons

.button {
  color: white;
  background-color: #cc0000;
  border: 3px solid;
  border-color: black;
  width: 275px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  font-size: 18px;
  font-family: "Helvetica-Neue";
  font-weight: bold;
  -webkit-border-radius: 10px; /* rounded */
  -webkit-box-shadow: 0px 2px gray;
  text-shadow: 0px 0px 8px black;
  background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, 
    from(rgba(255,255,255,0.5)), to(rgba(255,255,255,0.2)),
    color-stop(.5,rgba(255,255,255,0.3)), color-stop(.5,rgba(255,255,255,0.0))
  );
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
}
Button
function enable(b) {
  button.style.backgroundColor = 'blue';
}
function disable(b) {
  button.style.backgroundColor = 'red';
}

Caching with an HTML5 database

if ( window.openDatabase ) { // check availability
  var db = openDatabase( "db", "1.0", "displayName", 250000 ); // expected size
}
  • Just the name is required
db.transaction( function(tx) { 
  tx.executeSQL( "create table t (id integer, item text)" );
});
  • webkit.org sticky notes example

Game Center

Provides

  • friends
  • leaderboards
  • achievements
  • multiplayer

Closures in iOS4 and OSX 10.6

Called "blocks" by Apple

{
  int x = 2;
  void (^closure)(int) = ^(int y) {
    printf( "%d %d", x, y );
  }
  closure( 3 ); // prints "2 3"
}
  • Used for a lot of GameKit calls to implement async.

Signing in

  • GKLocalPlayer = the player on this device
  • authenticateWithCompletionHandler

Friends

  • GKPlayer = another player
  • loadFriendsWithCompletionHandler

Leaderboards

  • GKScore - for reporting scores
  • GKLeaderboard - for querying the leaderboard
  • GKLeaderboardViewController - modal view controller to display leaderboard
  • First need to setup leaderboard in iTunesConnect

Achievements

  • GKAchievementDescription - get available achievements
  • GKAchievement - for reporting an achievement, and getting a user's achievements
  • GKAchievementViewController - UI
  • Setup within iTunesConnect

Similar to leaderboards.

Multiplayer

Auto Match

  • GKMatchRequest - parameters of match, sent to server
  • GKMatchmaker - used to make request, returns GKMatch
  • GKMatchmakerViewController - view of matches
  • GKMatch - provides peer-to-peer comms functionality
  • GKPlayer array is returned instead of GKMatch if client-server model.

Invites

  • via GKMatchmakerViewController - inviter
  • uses push notifications
  • GKInvite
  • Invitee - implement inviteHandler, can be called at any time.
  • playersToInviteHandler - for server based. Both on shared GKMatchMaker object.

Comms

  • GKMatch object
  • In-voice available only on peer-to-peer, with GKVoiceChat

Process: Signing and Certificates

Certificate Expired

  • Generate and submit CSR with KeyChainAccess
  • Download certificate

Provisioning Expired

  • Modify dev and dist profiles to use the new certificate is necessary
  • Download and install in keychain.
  • Delete expired if necessary

Process: Ad-Hoc Build

Setup

  • Duplicate Release configuration and rename Ad-Hoc
  • Change to use Ad-Hoc certification
  • Manage Schemes
  • Configure Archive to use Ad-Hoc

Release

  • Update the version
    • Click on target, info; update bundle version, bundle versions string; short.
  • Product->Edit Schemes. Select Archive
  • Product->Archive
  • Archive (.ipa)
  • Include .ipa and .mobileprovision when distributing

Full details

Testing the ipa

unzip file.ipa
  • look for embedded.mobileprovision to check valid devices