Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
iOS for Web Developers
Search
Ben Howdle
August 22, 2014
Programming
310
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS for Web Developers
Ben Howdle
August 22, 2014
Other Decks in Programming
See All in Programming
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
210
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
320
Webフレームワークの ベンチマークについて
yusukebe
0
180
セキュリティの専門家じゃなくてもできる。「セキュリティ意識」をアップデートして サプライチェーン攻撃への耐性を高めよう。
tk3fftk
5
990
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
7.1k
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
240
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
120
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
200
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
270
スマートグラスで並列バイブコーディング
hyshu
0
270
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
990
はてなアカウント基盤 State of the Union
cockscomb
1
1.1k
Featured
See All Featured
Speed Design
sergeychernyshev
33
1.9k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
570
Designing Powerful Visuals for Engaging Learning
tmiket
1
430
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Un-Boring Meetings
codingconduct
0
330
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
Between Models and Reality
mayunak
4
360
Skip the Path - Find Your Career Trail
mkilby
1
160
The untapped power of vector embeddings
frankvandijk
2
1.8k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
440
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
740
Optimizing for Happiness
mojombo
378
71k
Transcript
iOS for web developers site: http://benhowdle.im twitter: @benhowdle
Today’s menu • Why give this talk? • An Objective-C
crash course • The building blocks of an iOS app • New things • Warm & fuzzy familiar things • Greener pastures & pain-points
Why give this talk?
http://benhowdle.im/2014/04/24/ios-for-web-developers-building-permeate/
None
Objective-C .page > #menu li:nth-child(2n+1) ~ a:focus Not so fast
on the hatin’
Classes & Objects
JavaScript //definition ! function MyClass(name){ this.name = name; } !
myClass.prototype.sayName = function(){ console.log(this.name); } ! // usage ! var myClass = new MyClass("woz"); myClass.sayName(); // woz
Objective-C // definition ! // MyClass.h @interface MyClass : NSObject
! @property NSString *name; ! - (id)initWithName:(NSString *)name; - (void)sayName; ! @end // MyClass.m #import "MyClass.h" ! @implementation MyClass - (id)initWithName:(NSString *)name { if ((self = [super init])) { _name = name; } return self; } ! - (void)sayName { NSLog(@"%@", self.name); } @end ! // usage ! MyClass *myClass = [[MyClass alloc] initWithName:@"woz"]; [myClass sayName]; Interface (header) file Implementation file
Variables
JavaScript var myNum = 2; var myDictionary = { foo:
"bar" } var myArray = ["foo", "bar"];
Objective-C NSNumber *myNum = @2; NSDictionary *myDictionary = @{ @"foo":
@"bar" } NSArray *myArray = @[@"foo", @"bar"];
Methods (functions)
JavaScript function takeMyMoney(amount, inCurrency){ console.log(inCurrency + amount); } ! function
takeMyMoney(amount, inCurrency, withAReceipt){ console.log(withAReceipt); return inCurrency + amount; } ! takeMyMoney(42, "£"); // £42 takeMyMoney(42, "£", true); // £42
Objective-C - (void)takeMyMoney:(NSNumber *)amount inCurrency:(NSString *)currency { NSLog(@"%@%@", currency, amount);
} ! - (NSString *)takeMyMoney:(NSNumber *)amount inCurrency:(NSString *)currency withReceipt:(BOOL)receipt { NSLog(@"%@", receipt ? @"YES" : @"NO"); return [NSString stringWithFormat:@"%@%@", currency, amount]; } ! [self takeMyMoney:@42 inCurrency:@"£"]; // £42 NSString *monies = [self takeMyMoney:@42 inCurrency:@"£" withReceipt:YES]; // £42
Anatomy of an iOS app
View Controllers
Objective-C @interface FooViewController : UIViewController ! @end #import "FooViewController.h" !
@interface FooViewController () ! @end ! @implementation FooViewController ! - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; } ! @end
Objective-C - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ! self.window =
[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UIViewController *vc = [[ViewController alloc] init]; self.window.rootViewController = vc; [self.window makeKeyAndVisible]; return YES; ! }
UIViewController UITableViewController UINavigationController
Views
JavaScript var button = document.createElement('div'); button.innerHTML = "Click me"; button.style.backgroundColor
= "#f7f7f7"; button.style.color = "#222"; button.style.borderRadius = "4px"; button.style.width = "100px"; button.style.height = "25px"; document.querySelector('#mySidebar').appendChild(button);
Objective-C UIButton *myButton = [[UIButton alloc] init]; myButton.frame = CGRectMake(0,
0, 100, 25); [myButton setTitle:@"Tap me" forState:UIControlStateNormal]; myButton.layer.cornerRadius = 4; myButton.backgroundColor = [UIColor blueColor]; myButton.titleLabel.textColor = [UIColor whiteColor]; [self.view addSubview:myButton];
New things to learn
Multithreading
Objective-C dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKG ROUND, 0), ^ { // intensive stuff, maybe
a network request, or resizing an image dispatch_async(dispatch_get_main_queue(), ^{ // back on the main thread to update the UI }); });
Dependency Management
Delegates
Objective-C - (void)viewDidLoad { [super viewDidLoad]; self.passwordTextField = [[UITextField alloc]
initWithFrame:CGRectMake(10, 316, 300, 44)]; self.passwordTextField.placeholder = @"Password"; self.passwordTextField.secureTextEntry = YES; self.passwordTextField.delegate = self; [self.view addSubview:self.passwordTextField]; } ! -(BOOL)textFieldShouldReturn:(UITextField *)textField { if(textField == self.passwordTextField){ [textField resignFirstResponder]; // do what we want now return NO; } return YES; }
No HTML
Typed language
Warm, fuzzy familiar things
Handling Events
JavaScript document.querySelector('#myButton').addEventListener('click', handleClick); ! function handleClick(){ console.log('I was clicked'); }
Objective-C UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; ! [self.myButton
addGestureRecognizer:singleFingerTap]; ! - (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { NSLog(@"I was tapped"); }
Blocks
JavaScript function someTask(callback){ // do some stuff callback(); } !
someTask(function(){ // someTask has been completed }); ! function someTaskThatReturnsAName(callback){ callback("Neo"); } ! someTaskThatReturnsAName(function(name){ console.log(name); });
Objective-C - (void)someTask:(void (^)(void))callback { // do some stuff callback();
} ! [self someTask:^{ // someTask has been completed }]; ! - (void)someTaskThatReturnsAName:(void (^)(NSString *))callback { // do some stuff callback(@"Neo"); } ! [self someTaskThatReturnsAName:^(NSString *name){ NSLog(@"%@", name); }];
Package Management
Images
HTML <img src="/images/face.png" /> <img src="http://www.placecage.com/g/200/300" />
Objective-C // local UIImage *img = [UIImage imageNamed:@"bg.jpeg"]; ! //
remote UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL: [NSURL URLWithString:@"http://www.placecage.com/g/200/300"]]]; ! UIImageView *bg = [[UIImageView alloc] initWithImage:img]; [self.view addSubview:bg]; https://github.com/nicklockwood/AsyncImageView
AJAX & JSON
JavaScript var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://www.reddit.com/r/earthporn.json', true); !
xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ console.log(JSON.parse(xhr.responseText).data.children); } } ! xhr.send();
Objective-C NSURL *url = [NSURL URLWithString:@"http://www.reddit.com/r/earthporn.json"]; ! NSURLSessionDataTask *dataTask =
[[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if(error == nil){ id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSArray *results = [json valueForKeyPath:@“data.children”]; NSLog(@"%@", results); } }]; ! [dataTask resume];
Greener pastures
Fewer screen sizes
Xcode
Documentation
Views (vs. HTML)
Pain points
Learning curve
Deployments & updating
Provisioning Portal
Thanks for listening…