Binding Objective C into Xamarin

Our urge to use a Native library in MonoTouch environment is so much, yet we face difficulty in doing so on weekly if not daily basis. I personally found Xamarin developer documents are not so straightforward and clear in understanding. In this binding process our ultimate goal is to convert “Cocoa Touch Library” or “Cocoa Touch Framework” to “.dll”. The process of binding of “Cocoa Touch Library” and “Cocoa Touch Framework” are little different.

Binding Objective C library :

Before we start you please create a folder and keep the fat or universal library (.a file) and all the corresponding header files. If you are unaware of Fat Library then check out my article.  

  1. Convert .h file into .cs file.
    1. Download and install a command line tool called Objective Sharpie
    2. Open Terminal
    3. Type Command:  sharpie bind -output Binding -sdk iphoneos8.1  Path of your .h file    
    4. iphoneos8.1 will be your Xamarin Studios’s iOS target version
    5. Hit enter and you get ApiDefinitions.cs and StructEnum.cs in your home directory.
    6. ApiDefinitions.cs file contains the C# version of the methods, protocols, properties etc. of the .h files. There may be multiple .h files you have but after conversion it keep all the classes inside the same file.
    7. StructEnum.cs as the name suggests it contains the “struct” “enum” which was part of .h files.

 

Tips (you can skip): You can convert .h file manually also, without using “Objective Sharpie Tool” but it’s a tedious process, you have to convert each and every line of the header file. We generally don’t have so much time, do you? Even if you use “Objective Sharpie Tool” you still have to fix some compiler errors but it will be very less. If Sharpie tool will not be 100% sure about the conversion then it  puts a “Verify” tag on top the line. For instance when it converts @protocol to Interface, it starts its name with “I” and it looks like ISomeDelegate and it gives error, which simply can be resolved by removing “I”.

 

  1. Create a binding project in Xamarin Studio.
    1. Under resources directory add the .a file and it will eventually create libSomething.linkwith.cs.
    2. In libSomething.linkwith.cs you will have to define the frameworks it needs while executing.
    3. Replace the code of the ApiDefinitions.cs and StructEnum.cs which you just converted.
    4. Set ForceLoad and SmartLink to “true”.
    5. Compile the binding project and you will get .dll inside the Bin folder of the project.

Binding Objective C Framework:

Cocoa touch framework contains “.exec” file along with header files (.h file).

  1. Just change the name of .exec file eg. SampleFramework.exec to libSampleFramework.a and follow the same process as we did for Objective C libraries. That it!
  2. If the framework has a .bundle, copy this to your project (not the bindings project), be aware not to the binding project! It needs to be added to resource folder of your solution this is because resources in Xamarin.iOS are not supported in DLLs.

 

I had spent so much time in figuring out about binding that I ended up writing this short and crisp article to help fellow developers. If this doesn’t solve your problem reach me out I will definitely try to help! I may convert and give it you for few bucks 🙂

 

Attributes of @property : nonatomic, retain, strong, weak etc..

This article is intended to be a reference guide to the property attributes.

By default @property looks like this:

@property(atomic,readwrite,strong)NSString *name;

or

@property(atomic,readwrite,assign)NSInteger age;

Access Attributes:

readonly : As the name suggests, value cannot be assigned to the object. It omits the setter method.

readwrite : Value of object can be assigned as well as retrieved from other object.

Threading Attribute:

atomic : Declaring a property atomic makes compiler generate additional code that prevents concurrent access to the object by multiple threads.

This additional code locks a semaphore, then gets or sets the property, and then unlock the semaphore. Locking and unlocking a semaphore is expensive (although it is usually negligible) but it ensures the setting or getting process completed entirely.

nonatomic : It specifies that accessors methods simply set or return a value directly, with no guarantee about what happens if that same value is accessed simultaneously from different threads. For this reason, it’s faster to access a nonatomic property than an atomic one.

Memory Management Attributes / lifetime qualifiers :

Many languages accomplish memory management through garbage collector, but Objective-C uses a more efficient alternative called object ownership or reference counting.

strong / retain : Declaring strong means that you want to “own” the object you are referencing. The compiler will take care that any object that you assign to this property will not be destroyed as long as you or any other object points to it with a strong reference.

In Objective-C, an object is kept alive as long as it has at least one strong reference to it from another object.

In non-ARC code strong is just a synonym for retain.

A variable maintains a strong reference to an object only as long as that variable is in scope, or until it is reassigned to another object or nil.

weak : It signifies that “keep the object in memory as long as someone else points to it strongly” and you don’t want to have control over the object’s lifetime. The object you are referencing weakly only lives on because some object holds a strong reference to it once that object loses its reference this object will be destroyed.

Assign : It assigns the new value, mostly this is been used with primitive data types like int, float , NSInteger, etc.

copy : It is needed when the object is mutable. Use this if you need the value of the object as it is at the moment, and you don’t want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.

It copies the value to a different memory location and it increases the retain count, which will be released when you no longer own it but in non ARC environment it needs to be released explicitly.

Note: If you are declaring a Mutable property with copy attribute then it will actually be immutable even though you declare it mutable. When you try to append value to it, it will throw exception.

unsafe_unretained : There are a few classes in Cocoa and Cocoa Touch that don’t yet support weak references, which means you can’t declare a weak property or weak local variable to keep track of them. It specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong references to the object. If the object it references is deallocated, the pointer is left dangling.

getter= : To use custom name for the getter method.

setter= : To use custom name for the setter method.

How @property works in Objective C

The goal of the @property directive is to configure how an object can be exposed. If you intend to use a variable inside the class and do not need to expose it to outside classes, then you do not need to define a property for it. Properties are basically the accessor methods.

Its all about encapsulation. Properties and its belongings like strong, weak, assign etc. are here to help in encapsulating objects and its value.

Without properties also one can pass objects but in a well-designed object-oriented program, it’s not advisable to directly access the value of an object.

Code snippet for passing raw object which is not advised to be used:

@interface LoginViewController : UIViewController{
//Declare public variable without declaring @property
@public NSString* username;
}
@end
@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];

LoginViewController loginViewController = [[LoginViewController alloc]init];

//Access the variable here.
loginViewController->username = @”Cocoa-juice”;

OR

(*loginViewController).username = @”Cocoa-juice”;

}

@end
Prior to the introduction of properties, methods were required to perform the work of a property but that require the similar code to be written in multiple places. So @property does the job elegantly under the hood.

What it does under the hood?

  • It declares accessor methods (getter and setter) but it doesn’t not define (Lets be clear).
  • Accessor methods are defined by @synthesize directive. Apple developer link for this statement can be verified.
  • Though Objective-C properties are synthesised by default when not explicitly implemented from Xcode 4.4 (LLVM Compiler 4.0) onwards.
  • Use of the @synthesize statement in a class’s implementation block is to tell the compiler to create method definition that matches the specification you gave in the @property declaration.

@property (retain, nonatomic) NSString* name;

Generates below code:

-(NSString*)name;
-(void)setName:(NSString*)userName;


@synthesize name;

Generates below code:
-(NSString*)name{
return _name;

}

-(void)setName:(NSString*)name{
}

example :
self.name = @”cocoa-juice”;
loginViewController.name = self.name;
It eventually calls the accessor methods.

Note: Dot syntax Is a Concise Alternative to accessor method calls which can be used to access the value of the object.

App Thinning – Reduces iOS App size by 40%

Well, you’ve probably figured it out from the title that, this article is about how to reduce app’s footprint and improve user experience while targeting a wide range of iOS and watchOS devices.

In WWDC ‘15 June event Apple released iOS9 and tried to address storage concerns by reducing its own OS size from 4.58 GB(iOS 8 Size) to 1.3 GB(iOS 9 Size) and introduced a brand new feature known as ‘app thinning.’

Each universal iOS app binary you download contains a whole bunch of code for a whole bunch of devices, app that supports from iPhone 4s to 6 plus,  iPad 2 to iPad Air 2  contains assets for all these variants.

Apps are getting storage-hungry as and when a new resolution of device gets introduced. Things gets even worse in case of Game application which have multiple levels and it needs to keep all the multimedia (images, videos audio etc.) for all variants of devices. Even when user is in first level it still have to keep assets of 100th level.

Apple! as always tries to solve the problem from the root, came to rescue and introduced App Thinning.

With app thinning, Apple makes it a whole lot easier for developers to split up their apps such that users only download the code and asset that they actually need.

Developers will still upload the entire assets and code to App Store as they do now. App Store and iOS will handle the rest to deliver device-specific variant of those apps.

For inApp-Purchase applications iOS and AppStore will download and keep the required resources ready when user will unlock the paid feature. This feature will be supported from iOS 9 onwards. It will ensure apps use the lowest amount of storage on a device by only downloading the parts it needs to run on individual handsets.

The assets which one app is no longer using will be removed by the OS to keep storage free for other apps to run.

app_thinning_2x

image from Apple

What Apple documentation says about this

The App Store and operating system optimize the installation of iOS and watchOS apps by tailoring app delivery to the capabilities of the user’s particular device, with minimal footprint. This optimization, called app thinning, lets you create apps that use the most device features, occupy minimum disk space, and accommodate future updates that can be applied by Apple. Faster downloads and more space for other apps and content provides a better user experience.

Apps that take advantage of app thinning will see their download size reduced by around 20 to 40%, it will be a major boon for entry level devices of storage 8gb or 16gb.

But having said the above, beta testing of the application will have more importance in future, especially while supporting offline mode.

There are three components of app thinning: Slicing, Bitcode, and On-Demand resources.

Shortly I will be writing the next section on this topic – How to do ‘App Thinning’ programmatically.

Abstraction Vs Encapsulation

This is one of the most frequently asked and discussed question and I found it really confusing in my early stages of programming. Both are indeed very much different.

Abstraction

Abstraction represents taking out expected behaviour from an object. It can be achieved by using protocol (abstract class or interface in C# or Java). It is just about exposing behaviour what is expected from it.

Example: Pizza Hut! when you order pizza you only care about pizza to be delivered at your door, you don’t care how it’s cooked. Abstraction means to define methods whose purpose is to be extended/implemented only, I mean you need to be aware of that once you order pizza you will receive it hot and tasty.

Advantages of Abstraction

Abstraction lets you focus on what the object does instead of how it does.

Encapsulation

Encapsulation is a way to hide functionality (Methods) & Data (Variables) in a Class, which is not usable by other object or it may not be safe if accessible. It can be achieved by access modifiers like public, protected or private.

Example:

Suppose one class  has a method called doIncreaseCount()   which increments count global variable every hour and this variable is public, so some other object which have access to this object can change the value in between intentionally.  Then method doIncreaseCount() will not be able to provide desired result.

Following are the ways to make variable private in Objective C.

Inside .m file

@interface LoginManager{

NSMutableString *_mAuthenticationResult;

NSString *_mUsername;

}

OR

Inside .h file

@interface LoginManager{

@property (nonatomic, strong, readonly) LoginViewController *loginViewController;

}

OR

Inside .h file

@interface LoginManager{

@private

NSString *username;

}

and no @property definition, if you provide @property (nonatomic, strong) LoginViewController *loginViewController it will still be visible to other objects.

Advantages of Encapsulation

Encapsulation helps make code more flexible and maintainable by keeping related data in a single unit and on change it will not affect other module.

Universal or Fat static library

This post is about how to create universal or fat library and presuming that you already know how to create a static library. We generally use third party static library which works mostly across all architectures (i386, armv7, armv7s, arm64). These libraries have all the slices, one slice for an architecture. So, the more number of architecture you support the bigger the size of library will be.

Enough said now the steps:

1. Include all the architectures you need under architecture and valid architecture section as shown in screenshot.

Screen Shot 2015-06-20 at 8.32.19 pm

2. Select target device as simulator and run the project.

3. Select target device as iOS device and run the project.

Screen Shot 2015-06-20 at 8.03.39 pm

4. Copy two folders Debug-iphoneos and Debug-iphonesimulator to desktop.

5. Open terminal and type : lipo -create  path of .a file from iphonesimulator folder        path of .a file from iphoneos folder   -output universallib.a

6. Instead of writing path of file you can drag the .a file directly to terminal.

7. Done! you can find the universal library in your home directory.

8. Curious if architectures got included or not type the command:

 file path of the universalLib.a

or

lipo -info path of the universalLib.a

NOTE : Don’t connect iPhone or iPad while generating .a, else you may get only slice of that architecture. eg. If you connect iPhone 6 then you will only get arm64 bit slice of .a file.