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
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
100
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
410
源内ハンズオン概要編
hideg
0
240
Deep dive into the select statement (GopherCon UK)
jespino
0
170
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
340
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.3k
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
240
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
800
初めての模倣学習とVLA
natsutan
0
420
Go 1.27からのGODEBUG / Go 1.27 リリースパーティ #go127party
mazrean
0
280
PyO3 で既存 Python 評価器を Rust core 化する ー wasm-bindgen でブラウザにも配るための設計
kdash
1
270
AIに既存システムを理解させる技術 ~レガシーを見捨てないハーネスエンジニアリング入門~
ochtum
0
200
Featured
See All Featured
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
410
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
260
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.8k
The Invisible Side of Design
smashingmag
301
52k
Producing Creativity
orderedlist
PRO
348
41k
Marketing to machines
jonoalderson
1
5.7k
Automating Front-end Workflow
addyosmani
1369
210k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
640
[SF Ruby Conf 2025] Rails X
palkan
2
1.3k
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…