SlideShare a Scribd company logo
to the next level
John Sundell
Lead iOS Developer, Spotify
@johnsundell
Objective-CTaking
Objective-C ?
I ❤
Sometimes you
can’t use it :(
C++
""""""""""
""""""""""
""""""""""
""""""""""
""""""""""
""""""""""
##########
##########
##########
+ iOS 7
The time you would spend on a
rewrite could instead be spent on
building cool features foryour users.
I ❤
[Obj-C]
Objective - ?
TOTHE MACRO-MOBILE!
#define OPTIONAL(variable)
#define IF_LET(variable, block)
#define GUARD_LET(variable, block)
#define OPTIONAL(variable)
#define IF_LET(variable, block)
#define GUARD_LET(variable, block)
5 ways you can make your
Objective-C code better * ,
while still being Objective-C.
5 ways you can make your
Objective-C code better * ,
while still being Objective-C.
*Predictable, readable, compile-time checked
1. Nullability
Having stricter rules about
nullability reduces errors
with unexpected nil values.
Setting *)loadSettingWithIdentifier:(NSString *)identifier;
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting. Must not be nil!
*
* @return A setting object
*
* @warning May return nil!
*/
- (
Setting *)loadSettingWithIdentifier:(NSString *)identifier;
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting. Must not be nil!
*
* @return A setting object
*
* @warning May return nil!
*/
- (
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting. Must not be nil!
*
* @return A setting object
*
* @warning May return nil!
*/
- ( Setting *)loadSettingWithIdentifier:(NSString *)identifier;nullable
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting. Must not be nil!
*
* @return A setting object
*
* @warning May return nil!
*/
- ( Setting *)loadSettingWithIdentifier:(NSString *)identifier;nullable
NS_ASSUME_NONNULL_BEGIN
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting. Must not be nil!
*
* @return A setting object
*
* @warning May return nil!
*/
- ( Setting *)loadSettingWithIdentifier:(NSString *)identifier;nullable
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting
*
* @return A setting object
*/
- ( Setting *)loadSettingWithIdentifier:(NSString *)identifier;nullable
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END
/**
* Load a setting with a given identifier
*
* @param identifier The identifier of the setting
*
* @return A setting object
*/
- ( Setting *)loadSettingWithIdentifier:(NSString *)identifier;nullable
NS_ASSUME_NONNULL_BEGIN
NS_ASSUME_NONNULL_END Cleaner, self-documenting interface $
[settingsLoader loadSettingWithIdentifier:nil];
- (BOOL)isSettingEnabledForIdentifier:(nullable NSString *)identifier
{
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
- (BOOL)isSettingEnabledForIdentifier:(nullable NSString *)identifier
{
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
No compilerwarning %
- (BOOL)isSettingEnabledForIdentifier:(nullable NSString *)identifier
{
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
No compilerwarning %
Incorrect Uses Of NullableValues:YES
- (BOOL)isSettingEnabledForIdentifier:(nullable NSString *)identifier
{
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
Incorrect Uses Of NullableValues:YES
- (BOOL)isShuffleSettingEnabled
{
NSString *identifier = nil;
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
- (BOOL)isShuffleSettingEnabled
{
NSString *identifier = nil;
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
No compilerwarning %
- (BOOL)isShuffleSettingEnabled
{
NSString *identifier = nil;
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
No compilerwarning %
StaticAnalyzerto the rescue!
- (BOOL)isShuffleSettingEnabled
{
NSString *identifier = nil;
return [self loadSettingWithIdentifier:identifier].isEnabled;
}
StaticAnalyzerto the rescue!
2. Constants
Constants are great, because
they increase predictability of
our code, and reduce state.
let string = "Hello"
let string = "Hello"
string = "World"
let string = "Hello"
string = "World"
let string = "Hello"
string = "World"
NSString * const string = @"Hello";
let string = "Hello"
string = "World"
NSString * const string = @"Hello";
string = @"World";
let string = "Hello"
string = "World"
NSString * const string = @"Hello";
string = @"World";
class Model {
let identifier: NSUUID
}
class Model {
let identifier: NSUUID
}
@interface Model : NSObject
@property (nonatomic, strong, readonly) NSUUID *identifier;
@end
class Model {
let identifier: NSUUID
}
@interface Model : NSObject
@property (nonatomic, strong, readonly) NSUUID *identifier;
@end
self.identifier = [NSUUID UUID];
class Model {
let identifier: NSUUID
}
@interface Model : NSObject
@property (nonatomic, strong, readonly) NSUUID *identifier;
@end
self.identifier = [NSUUID UUID];
3. Designated initializers
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController;
@end
NS_DESIGNATED_INITIALIZER
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController ;
@end
NS_DESIGNATED_INITIALIZER
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController ;
DataLoader * const dataLoader = [[DataLoader alloc] init];
@end
NS_DESIGNATED_INITIALIZER
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController ;
DataLoader * const dataLoader = [[DataLoader alloc] init];
@end
No compilerwarning %
NS_DESIGNATED_INITIALIZER
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController ;
@end
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
DataLoader * const dataLoader = [[DataLoader alloc] init];
No compilerwarning %
NS_DESIGNATED_INITIALIZER
@interface DataLoader : NSObject
- (instancetype)initWithNetworkController:(NetworkController *)networkController ;
@end
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
DataLoader * const dataLoader = [[DataLoader alloc] init];
By enforcing the use of a
designated (or convenience)
initializer, we can make sure our
objects are set up correctly.
4. Manage weak references
@interface AnimationController : NSObject
@property (nonatomic, weak, nullable) id<AnimationDelegate> delegate;
- (void)performAnimation:(Animation *)animation;
@end
@interface AnimationController : NSObject
@property (nonatomic, weak, nullable) id<AnimationDelegate> delegate;
- (void)performAnimation:(Animation *)animation;
@end
@protocol AnimationDelegate <NSObject>
- (void)animationController:(AnimationController *)controller
animationDidBegin:(Animation *)animation;
- (void)animationController:(AnimationController *)controller
animationDidEnd:(Animation *)animation;
- (BOOL)animationController:(AnimationController *)controller
shouldRepeatAnimation:(Animation *)animation;
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
Delegate may be released
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end No compilerwarning %
Delegate may be released
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end No compilerwarning %
Repeatedly using a __weak reference:YES
Delegate may be released
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
[self.delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [self.delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[self.delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
Repeatedly using a __weak reference:YES
Delegate may be released
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
id<AnimationDelegate> const delegate = self.delegate;
[delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
@implementation AnimationController
- (void)performAnimation:(Animation *)animation
{
id<AnimationDelegate> const delegate = self.delegate;
[delegate animationController:self
animationDidBegin:animation];
[animation playWithCompletionHandler:^{
BOOL const shouldRepeat = [delegate animationController:self
shouldRepeatAnimation:animation];
if (shouldRepeat) {
[self performAnimation:animation];
} else {
[delegate animationController:self
animationDidEnd:animation];
}
}];
}
@end
Predictable delegate behavior $
When references are released
unexpectedly, it can put our
app in an undefined state.
5. Strong typing
id
id
NSString
NSURL
UIView
UIColor
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
* const array = @[color];
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
* const array = @[color];
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
* const array = @[color];
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
* const array = @[color];
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
Generic annotations to the rescue!
* const array = @[color];
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
Generic annotations to the rescue!
* const array = @[color];<UIColor *>
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Runtime crash &
Generic annotations to the rescue!
* const array = @[color];<UIColor *>
id
NSString
NSURL
UIView
UIColor
NSString * const string = @“Hello";
UIColor * const color = [UIColor redColor];
NSArray
NSString * const combinedString = [string stringByAppendingString:array[0]];
Generic annotations to the rescue!
* const array = @[color];<UIColor *>
NSArray<ObjectType>
NSDictionary<KeyType, ObjectType>
NSSet<ObjectType>
NSArray<ObjectType>
NSDictionary<KeyType, ObjectType>
NSSet<ObjectType>
@interface Collection<__covariant ObjectType> : NSObject
- (void)addObject:(ObjectType)object;
@end
By retaining type information
throughout our code, we can
make our code more predictable.
Demo
1. Nullability
2. Constants
3. Designated initializers
4. Manage weak references
5. Strong typing
@johnsundell
josu@spotify.com
github.com/johnsundell

More Related Content

What's hot

Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
Stephen Vance
 
ARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマーARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマーSatoshi Asano
 
Nevermore Unit Testing
Nevermore Unit TestingNevermore Unit Testing
Nevermore Unit Testing
Ihsan Fauzi Rahman
 
solving little problems
solving little problemssolving little problems
solving little problems
Austin Ziegler
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the framework
GOG.com dev team
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
AngularJS: what is underneath the hood
AngularJS: what is underneath the hood AngularJS: what is underneath the hood
AngularJS: what is underneath the hood
DA-14
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Tsuyoshi Yamamoto
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
Kris Wallsmith
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
Joseph Chiang
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
Troy Miles
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code LabColin Su
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
Leon van der Grient
 

What's hot (20)

Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
AST Rewriting Using recast and esprima
AST Rewriting Using recast and esprimaAST Rewriting Using recast and esprima
AST Rewriting Using recast and esprima
 
ARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマーARCでめちゃモテiOSプログラマー
ARCでめちゃモテiOSプログラマー
 
Nevermore Unit Testing
Nevermore Unit TestingNevermore Unit Testing
Nevermore Unit Testing
 
solving little problems
solving little problemssolving little problems
solving little problems
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
Symfony without the framework
Symfony without the frameworkSymfony without the framework
Symfony without the framework
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
AngularJS: what is underneath the hood
AngularJS: what is underneath the hood AngularJS: what is underneath the hood
AngularJS: what is underneath the hood
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
Drupal 8: Fields reborn
Drupal 8: Fields rebornDrupal 8: Fields reborn
Drupal 8: Fields reborn
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code Lab
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 

Similar to Taking Objective-C to the next level. UA Mobile 2016.

Modernizes your objective C - Oliviero
Modernizes your objective C - OlivieroModernizes your objective C - Oliviero
Modernizes your objective C - Oliviero
Codemotion
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
jonmarimba
 
iOS
iOSiOS
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
Matthew Morey
 
iOS Einführung am Beispiel von play NEXT TEE
iOS Einführung am Beispiel von play NEXT TEEiOS Einführung am Beispiel von play NEXT TEE
iOS Einführung am Beispiel von play NEXT TEE
Hendrik Ebel
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCAWhymca
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
Fred Chien
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
Mark
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Sarp Erdag
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
Norberto Leite
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)
MongoDB
 
Pioc
PiocPioc
Pioc
Tom Sun
 
Modernize your Objective-C
Modernize your Objective-CModernize your Objective-C
Modernize your Objective-C
Massimo Oliviero
 
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with InfrastructorGr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Stanislav Tiurikov
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
Nuvole
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
SmartLogic
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdf
ShaiAlmog1
 
! Modernizr v2.0.6 httpwww.modernizr.com Copyri.docx
!  Modernizr v2.0.6  httpwww.modernizr.com   Copyri.docx!  Modernizr v2.0.6  httpwww.modernizr.com   Copyri.docx
! Modernizr v2.0.6 httpwww.modernizr.com Copyri.docx
MARRY7
 

Similar to Taking Objective-C to the next level. UA Mobile 2016. (20)

201104 iphone navigation-based apps
201104 iphone navigation-based apps201104 iphone navigation-based apps
201104 iphone navigation-based apps
 
Modernizes your objective C - Oliviero
Modernizes your objective C - OlivieroModernizes your objective C - Oliviero
Modernizes your objective C - Oliviero
 
303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code303 TANSTAAFL: Using Open Source iPhone UI Code
303 TANSTAAFL: Using Open Source iPhone UI Code
 
iOS
iOSiOS
iOS
 
Day 1
Day 1Day 1
Day 1
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
 
iOS Einführung am Beispiel von play NEXT TEE
iOS Einführung am Beispiel von play NEXT TEEiOS Einführung am Beispiel von play NEXT TEE
iOS Einführung am Beispiel von play NEXT TEE
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Mongo+java (1)
Mongo+java (1)Mongo+java (1)
Mongo+java (1)
 
Pioc
PiocPioc
Pioc
 
Modernize your Objective-C
Modernize your Objective-CModernize your Objective-C
Modernize your Objective-C
 
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with InfrastructorGr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
Gr8conf EU 2018 - Bring you infrastructure under control with Infrastructor
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Practical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails AppPractical Chef and Capistrano for Your Rails App
Practical Chef and Capistrano for Your Rails App
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdf
 
! Modernizr v2.0.6 httpwww.modernizr.com Copyri.docx
!  Modernizr v2.0.6  httpwww.modernizr.com   Copyri.docx!  Modernizr v2.0.6  httpwww.modernizr.com   Copyri.docx
! Modernizr v2.0.6 httpwww.modernizr.com Copyri.docx
 

More from UA Mobile

Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
UA Mobile
 
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
UA Mobile
 
Leave your Room behind - UA Mobile 2019
Leave your Room behind - UA Mobile 2019Leave your Room behind - UA Mobile 2019
Leave your Room behind - UA Mobile 2019
UA Mobile
 
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
UA Mobile
 
Google Wear OS watch faces and applications development - UA Mobile 2019
Google Wear OS watch faces and applications development - UA Mobile 2019Google Wear OS watch faces and applications development - UA Mobile 2019
Google Wear OS watch faces and applications development - UA Mobile 2019
UA Mobile
 
Історія декількох проектів та що в них пішло не так - UA Mobile 2019
Історія декількох проектів та що в них пішло не так - UA Mobile 2019Історія декількох проектів та що в них пішло не так - UA Mobile 2019
Історія декількох проектів та що в них пішло не так - UA Mobile 2019
UA Mobile
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
UA Mobile
 
Managing State in Reactive applications - UA Mobile 2019
Managing State in Reactive applications - UA Mobile 2019Managing State in Reactive applications - UA Mobile 2019
Managing State in Reactive applications - UA Mobile 2019
UA Mobile
 
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
UA Mobile
 
Актуальні практики дизайну мобільних додатків - UA Mobile 2019
Актуальні практики дизайну мобільних додатків - UA Mobile 2019Актуальні практики дизайну мобільних додатків - UA Mobile 2019
Актуальні практики дизайну мобільних додатків - UA Mobile 2019
UA Mobile
 
До чого прикладати Docker в Android? - UA Mobile 2019
До чого прикладати Docker в Android? - UA Mobile 2019До чого прикладати Docker в Android? - UA Mobile 2019
До чого прикладати Docker в Android? - UA Mobile 2019
UA Mobile
 
Building your Flutter apps using Redux - UA Mobile 2019
Building your Flutter apps using Redux - UA Mobile 2019Building your Flutter apps using Redux - UA Mobile 2019
Building your Flutter apps using Redux - UA Mobile 2019
UA Mobile
 
Optional. Tips and Tricks - UA Mobile 2019
Optional. Tips and Tricks - UA Mobile 2019Optional. Tips and Tricks - UA Mobile 2019
Optional. Tips and Tricks - UA Mobile 2019
UA Mobile
 
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
UA Mobile
 
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
UA Mobile
 
Flutter: No more boring apps! - UA Mobile 2019
Flutter: No more boring apps! - UA Mobile 2019Flutter: No more boring apps! - UA Mobile 2019
Flutter: No more boring apps! - UA Mobile 2019
UA Mobile
 
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
UA Mobile
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
UA Mobile
 
Sceneform SDK на практиці - UA Mobile 2019
Sceneform SDK на практиці - UA Mobile 2019Sceneform SDK на практиці - UA Mobile 2019
Sceneform SDK на практиці - UA Mobile 2019
UA Mobile
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
UA Mobile
 

More from UA Mobile (20)

Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
 
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
Декларативное программирование клиент-серверных приложений на андроид - UA Mo...
 
Leave your Room behind - UA Mobile 2019
Leave your Room behind - UA Mobile 2019Leave your Room behind - UA Mobile 2019
Leave your Room behind - UA Mobile 2019
 
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
OpenId and OAuth2: Rear, Medium, Well Done - UA Mobile 2019
 
Google Wear OS watch faces and applications development - UA Mobile 2019
Google Wear OS watch faces and applications development - UA Mobile 2019Google Wear OS watch faces and applications development - UA Mobile 2019
Google Wear OS watch faces and applications development - UA Mobile 2019
 
Історія декількох проектів та що в них пішло не так - UA Mobile 2019
Історія декількох проектів та що в них пішло не так - UA Mobile 2019Історія декількох проектів та що в них пішло не так - UA Mobile 2019
Історія декількох проектів та що в них пішло не так - UA Mobile 2019
 
Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019Working effectively with ViewModels and TDD - UA Mobile 2019
Working effectively with ViewModels and TDD - UA Mobile 2019
 
Managing State in Reactive applications - UA Mobile 2019
Managing State in Reactive applications - UA Mobile 2019Managing State in Reactive applications - UA Mobile 2019
Managing State in Reactive applications - UA Mobile 2019
 
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
Ідіоматична ін'єкція залежностей на Kotlin без фреймворків - UA Mobile2019
 
Актуальні практики дизайну мобільних додатків - UA Mobile 2019
Актуальні практики дизайну мобільних додатків - UA Mobile 2019Актуальні практики дизайну мобільних додатків - UA Mobile 2019
Актуальні практики дизайну мобільних додатків - UA Mobile 2019
 
До чого прикладати Docker в Android? - UA Mobile 2019
До чого прикладати Docker в Android? - UA Mobile 2019До чого прикладати Docker в Android? - UA Mobile 2019
До чого прикладати Docker в Android? - UA Mobile 2019
 
Building your Flutter apps using Redux - UA Mobile 2019
Building your Flutter apps using Redux - UA Mobile 2019Building your Flutter apps using Redux - UA Mobile 2019
Building your Flutter apps using Redux - UA Mobile 2019
 
Optional. Tips and Tricks - UA Mobile 2019
Optional. Tips and Tricks - UA Mobile 2019Optional. Tips and Tricks - UA Mobile 2019
Optional. Tips and Tricks - UA Mobile 2019
 
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...Designing iOS+Android project without using multiplatform frameworks - UA Mob...
Designing iOS+Android project without using multiplatform frameworks - UA Mob...
 
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
Бібліотеки та Інструменти на сторожі коду - UA Mobile 2019
 
Flutter: No more boring apps! - UA Mobile 2019
Flutter: No more boring apps! - UA Mobile 2019Flutter: No more boring apps! - UA Mobile 2019
Flutter: No more boring apps! - UA Mobile 2019
 
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
Долаючи прірву між дизайнерами та розробниками - UA Mobile 2019
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
 
Sceneform SDK на практиці - UA Mobile 2019
Sceneform SDK на практиці - UA Mobile 2019Sceneform SDK на практиці - UA Mobile 2019
Sceneform SDK на практиці - UA Mobile 2019
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 

Recently uploaded

Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
abdulrafaychaudhry
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 

Recently uploaded (20)

Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
 
Enhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdfEnhancing Research Orchestration Capabilities at ORNL.pdf
Enhancing Research Orchestration Capabilities at ORNL.pdf
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 

Taking Objective-C to the next level. UA Mobile 2016.