Sie sind auf Seite 1von 28

Clean, Secure and Fast iOS

Stefan Tsvyatkov
iOS Department Manager,

Galin Kardzhilov
Senior iOS Developer,

Andrey Marinov
Senior iOS Developer,

Clean, Secure and Fast iOS


!

Good security practices

Naming conventions in Objective-C


!

Under the hood of 64-bit development

Q&A
Clean, Secure and Fast iOS

Stefan Tsvyatkov
iOS Department Manager,

Galin Kardzhilov
Senior iOS Developer,

Andrey Marinov
Senior iOS Developer,

Clean, Secure and Fast iOS


!

Good security practices

Naming conventions in Objective-C


!

Under the hood of 64-bit development

Q&A

Clean, Secure and Fast iOS

Security in iOS

Local Storage

Communication with the server

Binary analysis and manipulation

Clean, Secure and Fast iOS

Local Storage Security


NSUserDefaults

Senior iOS Developer,

Clean, Secure and Fast iOS


!

Good security practices

Naming conventions in Objective-C


!

Under the hood of 64-bit development

Q&A

Clean, Secure and Fast iOS

Security in iOS

Local Storage

Communication with the server

Binary analysis and manipulation

Clean, Secure and Fast iOS

Local Storage Security


NSUserDefaults

re
Convenient

u
Not encrypted by default

ec
Keeps the data in a plist file

t s
No
CoreData

Not encrypted by default

Keeps the data in sqlite db

Clean, Secure and Fast iOS

Local Storage Security


Keychain Access
[[UIDevice currentDevice] identifierForVendor]

Encrypted by default

A bit more complex for use

Insecure on jailbroken devices String constant

Custom
algorithm

Data encryption

Crypto API

Obfuscate the encryption key

Use unique device information


Secure encryption key

Local Storage

Communication with the server

Binary analysis and manipulation

Clean, Secure and Fast iOS

Local Storage Security


NSUserDefaults

re
Convenient

cu
Not encrypted by default

Keeps the data in a plist file

s e
ot
CoreData

N
Not encrypted by default

Keeps the data in sqlite db

Clean, Secure and Fast iOS

Local Storage Security


Keychain Access
[[UIDevice currentDevice] identifierForVendor]

Encrypted by default

A bit more complex for use

Insecure on jailbroken devices String constant

Custom
algorithm

Data encryption

Crypto API

Obfuscate the encryption key

Use unique device information


Secure encryption key

Clean, Secure and Fast iOS

Server Communication Security

Use SSL

Dont accept self-signed certificates

Client and server side data validation

Clean, Secure and Fast iOS

Runtime Manipulation
ptrace

Deny a debugger to attach


#import "AppDelegate.h"
Clean, Secure and Fast iOS

Local Storage Security


Keychain Access
[[UIDevice currentDevice] identifierForVendor]

Encrypted by default

A bit more complex for use

Insecure on jailbroken devices String constant

Custom
algorithm

Data encryption

Crypto API

Obfuscate the encryption key

Use unique device information


Secure encryption key

Clean, Secure and Fast iOS

Server Communication Security

Use SSL

Dont accept self-signed certificates

Client and server side data validation

Clean, Secure and Fast iOS

Runtime Manipulation
ptrace

Deny a debugger to attach


#import "AppDelegate.h"
Can be patched from binary
#import "ptrace.h"
!
Put it in multiple places
int main(int argc, char * argv[])
{
#ifndef DEBUG
ptrace(PT_DENY_ATTACH, 0, 0, 0);
#endif
@autoreleasepool {
return UIApplicationMain(argc, argv,
nil, NSStringFromClass([AppDelegate class]));
}
}

Clean, Secure and Fast iOS

Runtime Manipulation
!

SEC_IS_BEING_DEBUGGED_RETURN_NIL()

#ifndef
! DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif
!

Check if a debugger is attached

Hard to be patched from binary

Make the check regularly and in critical parts

Doesnt work against Cycript


Use SSL

Dont accept self-signed certificates

Client and server side data validation

Clean, Secure and Fast iOS

Runtime Manipulation
ptrace

Deny a debugger to attach


#import "AppDelegate.h"
Can be patched from binary
#import "ptrace.h"
!
Put it in multiple places
int main(int argc, char * argv[])
{
#ifndef DEBUG
ptrace(PT_DENY_ATTACH, 0, 0, 0);
#endif
@autoreleasepool {
return UIApplicationMain(argc, argv,
nil, NSStringFromClass([AppDelegate class]));
}
}

Clean, Secure and Fast iOS

Runtime Manipulation
!

SEC_IS_BEING_DEBUGGED_RETURN_NIL()

#ifndef
! DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif
!

Check if a debugger is attached

Hard to be patched from binary

Make the check regularly and in critical parts

Doesnt work against Cycript

Clean, Secure and Fast iOS

Conclusion

Keychain Access for storing

SSL for transporting

Check for debuggers

100% security does not exist

Clean, Secure and Fast iOS

Why naming conventions are important?


- (NSDictionary *)determineKeyAdvantagesOfNamingConventions {
Clean, Secure and Fast iOS

Runtime Manipulation
!

SEC_IS_BEING_DEBUGGED_RETURN_NIL()

#ifndef
! DEBUG
SEC_IS_BEING_DEBUGGED_RETURN_NIL();
#endif
!

Check if a debugger is attached

Hard to be patched from binary

Make the check regularly and in critical parts

Doesnt work against Cycript

Clean, Secure and Fast iOS

Conclusion

Keychain Access for storing

SSL for transporting

Check for debuggers

100% security does not exist

Clean, Secure and Fast iOS

Why naming conventions are important?


- (NSDictionary *)determineKeyAdvantagesOfNamingConventions {
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];

result[@"Clarity"] = @"Code should be easy to read and understand. By


everyone!";
result[@"Consistency"] = @"Naming consistency an essential part of being a
great programmer.";
result[@"Expressiveness"] = @"Cocoa strongly encourages expressive, clear,
non-ambiguious names.";

return result;
}

Clean, Secure and Fast iOS

Class Naming
Class names are always capitalized Standard Classes
NSString
Objective-C doesnt have namespaces
NSMutableDictionary

Prefix your classes NSArray

Custom Classes
NS stands for NeXTSTEP
MCUser

MCEmailAttachment

MCServiceClient

Custom Subclasses
MCTableView

MCCollectionView
SSL for transporting

Check for debuggers

100% security does not exist

Clean, Secure and Fast iOS

Why naming conventions are important?


- (NSDictionary *)determineKeyAdvantagesOfNamingConventions {
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];

result[@"Clarity"] = @"Code should be easy to read and understand. By


everyone!";
result[@"Consistency"] = @"Naming consistency an essential part of being a
great programmer.";
result[@"Expressiveness"] = @"Cocoa strongly encourages expressive, clear,
non-ambiguious names.";

return result;
}

Clean, Secure and Fast iOS

Class Naming
Class names are always capitalized Standard Classes
NSString
Objective-C doesnt have namespaces
NSMutableDictionary

Prefix your classes NSArray

Custom Classes
NS stands for NeXTSTEP
MCUser

MCEmailAttachment

MCServiceClient

Custom Subclasses
MCTableView

MCCollectionView

MCView

Clean, Secure and Fast iOS

Variable names
camelCase
NSString *streetAddress = @"1 Infinite Loop";
NSString *cityName = @"Cupertino";
NSString *countyName = @"Santa Clara";

Clean, distinct names


NSString *HST_NM; // BAD: all caps and too terse
NSNumber *theip; // BAD: a word or abbreviation?
NSMutableArray *nsma; // BAD: completely ambiguous

Discouraged prefix with underscore


NSString *name; // correct!
NSString *_name; // _incorrect_

Clean, Secure and Fast iOS

Variable Names: Indicating Type


No need for common types like NSString, NSArray, NSNumber or BOOL
// Correct
NSString * accountName;
NSMutableArray * mailboxes;
NSArray * defaultHeaders;
Clean, Secure and Fast iOS

Class Naming
Class names are always capitalized Standard Classes
NSString
Objective-C doesnt have namespaces
NSMutableDictionary

Prefix your classes NSArray

Custom Classes
NS stands for NeXTSTEP
MCUser

MCEmailAttachment

MCServiceClient

Custom Subclasses
MCTableView

MCCollectionView

MCView

Clean, Secure and Fast iOS

Variable names
camelCase
NSString *streetAddress = @"1 Infinite Loop";
NSString *cityName = @"Cupertino";
NSString *countyName = @"Santa Clara";

Clean, distinct names


NSString *HST_NM; // BAD: all caps and too terse
NSNumber *theip; // BAD: a word or abbreviation?
NSMutableArray *nsma; // BAD: completely ambiguous

Discouraged prefix with underscore


NSString *name; // correct!
NSString *_name; // _incorrect_

Clean, Secure and Fast iOS

Variable Names: Indicating Type


No need for common types like NSString, NSArray, NSNumber or BOOL
// Correct
NSString * accountName;
NSMutableArray * mailboxes;
NSArray * defaultHeaders;
BOOL userInputWasUpdated;

Indicate all other types


UIImage * previewImage; // self-explanatory
UIActivityIndicatorView * uploadIndicator; // shows progress for uploads
NSUserDefaults * userDefaults; // only one of these, basic name ok

If a plural is not an NSArray or NSSet, specify it


NSDictionary * keyedAccountNames;
NSDictionary * messageDictionary;
NSIndexSet * selectedMailboxesIndexSet;

Clean, Secure and Fast iOS

Method Names
// Example from another language
object.begin(resource);
object.processData(resource, data, true);
object.end(true);

fileWrapper.write(path, true, true);

Cocoa/Objective-C
[fileWrapper writeToFile:path atomically:YES updateFilenames:YES];

// "Open the file with this application and deactivate.


!
[finder openFile:path withApplication:@"MailDrop" andDeactivate:YES];
NSString *HST_NM; // BAD: all caps and too terse
NSNumber *theip; // BAD: a word or abbreviation?
NSMutableArray *nsma; // BAD: completely ambiguous

Discouraged prefix with underscore


NSString *name; // correct!
NSString *_name; // _incorrect_

Clean, Secure and Fast iOS

Variable Names: Indicating Type


No need for common types like NSString, NSArray, NSNumber or BOOL
// Correct
NSString * accountName;
NSMutableArray * mailboxes;
NSArray * defaultHeaders;
BOOL userInputWasUpdated;

Indicate all other types


UIImage * previewImage; // self-explanatory
UIActivityIndicatorView * uploadIndicator; // shows progress for uploads
NSUserDefaults * userDefaults; // only one of these, basic name ok

If a plural is not an NSArray or NSSet, specify it


NSDictionary * keyedAccountNames;
NSDictionary * messageDictionary;
NSIndexSet * selectedMailboxesIndexSet;

Clean, Secure and Fast iOS

Method Names
// Example from another language
object.begin(resource);
object.processData(resource, data, true);
object.end(true);

fileWrapper.write(path, true, true);

Cocoa/Objective-C
[fileWrapper writeToFile:path atomically:YES updateFilenames:YES];

// "Open the file with this application and deactivate.


!
[finder openFile:path withApplication:@"MailDrop" andDeactivate:YES];

Clean, Secure and Fast iOS

Method Names: Accessors


No get prefix in accessors
// Incorrect // Correct
- (NSString *)getName; - (NSString *)name;
- (NSString *)getColor; - (NSString *)color;
! !
name = [object getName]; name = [object name];
color = [object getColor]; color = [object color];

// copy objects from the NSArray to the buffer


id *buffer = (id *) malloc(sizeof(id) * [array count]);
[array getObjects: buffer];

set prefix is always present


[object setName: name];
[object setColor: color];

Clean, Secure and Fast iOS

Adjectives
Property selectable, getter -isSelectable, setter -setSelectable:

BOOL selectable = [textView isSelectable];


BOOL editable = [textView isEditable];
Clean, Secure and Fast iOS

Method Names
// Example from another language
object.begin(resource);
object.processData(resource, data, true);
object.end(true);

fileWrapper.write(path, true, true);

Cocoa/Objective-C
[fileWrapper writeToFile:path atomically:YES updateFilenames:YES];

// "Open the file with this application and deactivate.


!
[finder openFile:path withApplication:@"MailDrop" andDeactivate:YES];

Clean, Secure and Fast iOS

Method Names: Accessors


No get prefix in accessors
// Incorrect // Correct
- (NSString *)getName; - (NSString *)name;
- (NSString *)getColor; - (NSString *)color;
! !
name = [object getName]; name = [object name];
color = [object getColor]; color = [object color];

// copy objects from the NSArray to the buffer


id *buffer = (id *) malloc(sizeof(id) * [array count]);
[array getObjects: buffer];

set prefix is always present


[object setName: name];
[object setColor: color];

Clean, Secure and Fast iOS

Adjectives
Property selectable, getter -isSelectable, setter -setSelectable:

BOOL selectable = [textView isSelectable];


BOOL editable = [textView isEditable];

[textView setSelectable: YES]; // no "is"


[textView setEditable: YES]; // no "is"

Cocoa relies heavily on key-value coding for much of its magic,

and KVC relies on properly-named accessors.

Clean, Secure and Fast iOS

Methods Names: Returning Objects


Based on conditions or input
[object/class thing+condition];
[object/class thing+input:input];
[object/class thing+identifer:input];

// Example
realPath = [path stringByExpandingTildeInPath];
fullString = [string stringByAppendingString:@Having a great time?];
object = [array objectAtIndex:3];

// class methods
newString = [NSString stringWithFormat:@"%f",1.5];
newArray = [NSArray arrayWithObject:newString];
// copy objects from the NSArray to the buffer
id *buffer = (id *) malloc(sizeof(id) * [array count]);
[array getObjects: buffer];

set prefix is always present


[object setName: name];
[object setColor: color];

Clean, Secure and Fast iOS

Adjectives
Property selectable, getter -isSelectable, setter -setSelectable:

BOOL selectable = [textView isSelectable];


BOOL editable = [textView isEditable];

[textView setSelectable: YES]; // no "is"


[textView setEditable: YES]; // no "is"

Cocoa relies heavily on key-value coding for much of its magic,

and KVC relies on properly-named accessors.

Clean, Secure and Fast iOS

Methods Names: Returning Objects


Based on conditions or input
[object/class thing+condition];
[object/class thing+input:input];
[object/class thing+identifer:input];

// Example
realPath = [path stringByExpandingTildeInPath];
fullString = [string stringByAppendingString:@Having a great time?];
object = [array objectAtIndex:3];

// class methods
newString = [NSString stringWithFormat:@"%f",1.5];
newArray = [NSArray arrayWithObject:newString];

Clean, Secure and Fast iOS

Methods Names: Returning Objects


Based on variation on a value
[object adjective+thing];
[object adjective+thing+condition];
[object adjective+thing+input:input];

// Example
capitalized = [name capitalizedString];
rate = [number floatValue];
newString = [string decomposedStringWithCanonicalMapping];
subarray = [array subarrayWithRange:segment];

Clean, Secure and Fast iOS

Avoid Ambiguity
// Ambiguous Messages
-sortInfo // returns sort info, or sort something called "info"?
-refreshTimer // return a timer used for refreshing, or refresh a timer?
-update // a verb? what is updated and how?
-fetchInfo: // fetch info about something or give info about a fetch?
Methods Names: Returning Objects
Based on conditions or input
[object/class thing+condition];
[object/class thing+input:input];
[object/class thing+identifer:input];

// Example
realPath = [path stringByExpandingTildeInPath];
fullString = [string stringByAppendingString:@Having a great time?];
object = [array objectAtIndex:3];

// class methods
newString = [NSString stringWithFormat:@"%f",1.5];
newArray = [NSArray arrayWithObject:newString];

Clean, Secure and Fast iOS

Methods Names: Returning Objects


Based on variation on a value
[object adjective+thing];
[object adjective+thing+condition];
[object adjective+thing+input:input];

// Example
capitalized = [name capitalizedString];
rate = [number floatValue];
newString = [string decomposedStringWithCanonicalMapping];
subarray = [array subarrayWithRange:segment];

Clean, Secure and Fast iOS

Avoid Ambiguity
// Ambiguous Messages
-sortInfo // returns sort info, or sort something called "info"?
-refreshTimer // return a timer used for refreshing, or refresh a timer?
-update // a verb? what is updated and how?
-fetchInfo: // fetch info about something or give info about a fetch?

// Clear Messages
-currentSortInfo // "current" obviously describes the noun "sort info"
-refreshDefaultTimer // refresh is now clearly a verb
-updateMenuItemTitle // an action is taking place
-infoForFetch: // now we know info is returned for a fetch

Clean, Secure and Fast iOS

Global C Functions
NSHomeDirectory()
Prefix + Value ()
NSHomeDirectoryForUser()
Prefix + Value + With/From/For + Input ()
NSClassFromString()
Prefix + Action ()
NSBeginAlertSheet()
Prefix + Action + Type ()
NSDrawGrayBezel()

Core Services Functions


// Core Foundation
CFArrayGetValueAtIndex() // returned directly, but "get" is still used
CFDictionaryGetValue()
CFDateGetAbsoluteTime()
!
// Core Graphics / Quartz
CGImageCreate()
CGImageGetHeight()
CGImageGetTypeID()
capitalized = [name capitalizedString];
rate = [number floatValue];
newString = [string decomposedStringWithCanonicalMapping];
subarray = [array subarrayWithRange:segment];

Clean, Secure and Fast iOS

Avoid Ambiguity
// Ambiguous Messages
-sortInfo // returns sort info, or sort something called "info"?
-refreshTimer // return a timer used for refreshing, or refresh a timer?
-update // a verb? what is updated and how?
-fetchInfo: // fetch info about something or give info about a fetch?

// Clear Messages
-currentSortInfo // "current" obviously describes the noun "sort info"
-refreshDefaultTimer // refresh is now clearly a verb
-updateMenuItemTitle // an action is taking place
-infoForFetch: // now we know info is returned for a fetch

Clean, Secure and Fast iOS

Global C Functions
NSHomeDirectory()
Prefix + Value ()
NSHomeDirectoryForUser()
Prefix + Value + With/From/For + Input ()
NSClassFromString()
Prefix + Action ()
NSBeginAlertSheet()
Prefix + Action + Type ()
NSDrawGrayBezel()

Core Services Functions


// Core Foundation
CFArrayGetValueAtIndex() // returned directly, but "get" is still used
CFDictionaryGetValue()
CFDateGetAbsoluteTime()
!
// Core Graphics / Quartz
CGImageCreate()
CGImageGetHeight()
CGImageGetTypeID()

Clean, Secure and Fast iOS

Other Global Symbols


CGPoint point; // struct
NSRange range; // struct

// search modes (enums)


NSLiteralSearch
NSCaseInsensitiveSearch

// exception names (constants)


NSMallocException
NSInvalidArgumentException

// notification names (constants)


UIKeyboardWillShowNotification Class of Aected Object + Did/Will + Action + "Notification"
NSManagedObjectContextDidSaveNotification

Clean, Secure and Fast iOS

Abbreviations
Abbreviations

int max min TIFF HTTP URL HTML PDF

rect temp info JPG FTP RTF XML ASCII


Global C Functions
NSHomeDirectory()
Prefix + Value ()
NSHomeDirectoryForUser()
Prefix + Value + With/From/For + Input ()
NSClassFromString()
Prefix + Action ()
NSBeginAlertSheet()
Prefix + Action + Type ()
NSDrawGrayBezel()

Core Services Functions


// Core Foundation
CFArrayGetValueAtIndex() // returned directly, but "get" is still used
CFDictionaryGetValue()
CFDateGetAbsoluteTime()
!
// Core Graphics / Quartz
CGImageCreate()
CGImageGetHeight()
CGImageGetTypeID()

Clean, Secure and Fast iOS

Other Global Symbols


CGPoint point; // struct
NSRange range; // struct

// search modes (enums)


NSLiteralSearch
NSCaseInsensitiveSearch

// exception names (constants)


NSMallocException
NSInvalidArgumentException

// notification names (constants)


UIKeyboardWillShowNotification Class of Aected Object + Did/Will + Action + "Notification"
NSManagedObjectContextDidSaveNotification

Clean, Secure and Fast iOS

Abbreviations
Abbreviations

int max min TIFF HTTP URL HTML PDF

rect temp info JPG FTP RTF XML ASCII

Clean, Secure and Fast iOS

Summary

Keep your code clean

Be consistent

Be descriptive
NSMallocException
NSInvalidArgumentException

// notification names (constants)


UIKeyboardWillShowNotification Class of Aected Object + Did/Will + Action + "Notification"
NSManagedObjectContextDidSaveNotification

Clean, Secure and Fast iOS

Abbreviations
Abbreviations

int max min TIFF HTTP URL HTML PDF

rect temp info JPG FTP RTF XML ASCII

Clean, Secure and Fast iOS

Summary

Keep your code clean

Be consistent

Be descriptive

Clean, Secure and Fast iOS

Moving on

LP64
Clean, Secure and Fast iOS

A new frontier

From ILP32 to LP64


Longs, Pointers are 64 bits

Summary

Keep your code clean

Be consistent

Be descriptive

Clean, Secure and Fast iOS

Moving on

LP64
Clean, Secure and Fast iOS

A new frontier

From ILP32 to LP64


Longs, Pointers are 64 bits

Integers still 32 bits

Same as OS X

Dierent than Windows LLP64

Clean, Secure and Fast iOS

The BOOL conundrum


- (BOOL)isNumber:(int) a differentThanNumber: (int) b {
return a - b;
}
!

if ([self isTheNumber:3 differentThanTheNumber:5]) {


// Did we make it here?
}

32-bit BOOL is a typedef-ed signed int


64-bit BOOL is _Bool, a real type

Clean, Secure and Fast iOS


Clean, Secure and Fast iOS

A new frontier

From ILP32 to LP64


Longs, Pointers are 64 bits

Integers still 32 bits

Same as OS X

Dierent than Windows LLP64

Clean, Secure and Fast iOS

The BOOL conundrum


- (BOOL)isNumber:(int) a differentThanNumber: (int) b {
return a - b;
}
!

if ([self isTheNumber:3 differentThanTheNumber:5]) {


// Did we make it here?
}

32-bit BOOL is a typedef-ed signed int


64-bit BOOL is _Bool, a real type

Clean, Secure and Fast iOS

Runtime optimizations

objc_class starts with the isa pointer

ARM64 uses only 30 bits of a pointer

Leads to performance boosts

Clean, Secure and Fast iOS

Optimizations

Inline reference count

Is reference count inline

Is referenced weakly flag

The BOOL conundrum


- (BOOL)isNumber:(int) a differentThanNumber: (int) b {
return a - b;
}
!

if ([self isTheNumber:3 differentThanTheNumber:5]) {


// Did we make it here?
}

32-bit BOOL is a typedef-ed signed int


64-bit BOOL is _Bool, a real type

Clean, Secure and Fast iOS

Runtime optimizations

objc_class starts with the isa pointer

ARM64 uses only 30 bits of a pointer

Leads to performance boosts

Clean, Secure and Fast iOS

Optimizations

Inline reference count

Is reference count inline

Is referenced weakly flag

Has associated objects flag

Has a C++ destructor flag

Clean, Secure and Fast iOS

Tagged pointers

Encodes value inline

Eliminates memory allocation

Provides performance boost

Clean, Secure and Fast iOS


Clean, Secure and Fast iOS

Optimizations

Inline reference count

Is reference count inline

Is referenced weakly flag

Has associated objects flag

Has a C++ destructor flag

Clean, Secure and Fast iOS

Tagged pointers

Encodes value inline

Eliminates memory allocation

Provides performance boost

Clean, Secure and Fast iOS

Tips and tricks

Use NSInteger/CGFloat
NSInteger ook = 4242424242424242;
NSLog (@"%ld",
(@"%@",
(@"%d", @(ook));
ook);
(long)ook);

warning: values of type 'NSInteger' should not be used as format


arguments;

add an explicit cast to 'long' instead [-Wformat]

Clean, Secure and Fast iOS

Conclusion

40-50% performance improvement

Definitely support 64-bit!

Tagged pointers

Encodes value inline

Eliminates memory allocation

Provides performance boost

Clean, Secure and Fast iOS

Tips and tricks

Use NSInteger/CGFloat
NSInteger ook = 4242424242424242;
NSLog (@"%ld",
(@"%@",
(@"%d", @(ook));
ook);
(long)ook);

warning: values of type 'NSInteger' should not be used as format


arguments;

add an explicit cast to 'long' instead [-Wformat]

Clean, Secure and Fast iOS

Conclusion

40-50% performance improvement

Definitely support 64-bit!

Higher memory usage

Untapped potential

Clean, Secure and Fast iOS

Questions?

Clean, Secure and Fast iOS


arguments;

add an explicit cast to 'long' instead [-Wformat]

Clean, Secure and Fast iOS

Conclusion

40-50% performance improvement

Definitely support 64-bit!

Higher memory usage

Untapped potential

Clean, Secure and Fast iOS

Questions?

Clean, Secure and Fast iOS

Contact Us

Stefan Tsvyatkov @stsvyatkov

Andrey Marinov @akmarinov

Galin Kardzhilov @gravera

#mobconbg

Clean, Secure and Fast iOS


Clean, Secure and Fast iOS

Contact Us

Stefan Tsvyatkov @stsvyatkov

Andrey Marinov @akmarinov

Galin Kardzhilov @gravera

#mobconbg

Clean, Secure and Fast iOS


#mobconbg

Clean, Secure and Fast iOS

Das könnte Ihnen auch gefallen