Move a UIButton (like a UIBarButtonItem) in a UINavigationBar

Change position of a UIButton (like a UIBarButtonItem) in a UINavigationBar is simple. So, you can change the margin of the navigationItem button, using the imageEdgeInsets property.

Be carefull… margin values are different in iOS6 and iOS7.

float v = [[[UIDevice currentDevice] systemVersion] floatValue];
    
    if(v>=7)
    {
        //for iOS7
    	UIButton *btnLeft = (UIButton *)self.navigationItem.leftBarButtonItem.customView;
        btnLeft.imageEdgeInsets = UIEdgeInsetsMake(0, -16, 0, 16);
    }
    else
    {
        //for iOS6
    	UIButton *btnLeft = (UIButton *)self.navigationItem.leftBarButtonItem.customView;
        btnLeft.imageEdgeInsets = UIEdgeInsetsMake(0, -5, 0, 5);
    }

That’s all!

RSBarcodes Framework for the best QR-BARCodes reader and generator

RSBarcodes would be the best QR/BARcodes reader and generator, for iOS.

RSBarcodes allows you to scan 1D and 2D barcodes using metadata scanning capabilities (introduced with iOS7) and generate the same set of barcode images for displaying and sharing.

I built the RSBarcodes Framework that helps you to implement the RSBarcodes into your project. For iOS5.1 and above, arm64 ready.

Just download the RSBarcodes project (with framework) from here and follow the Readme file.

That’s all!

iOS7 and UIRefreshControl in UIViewController (with UITableView)

A UIRefreshControl object provides a standard control that can be used to initiate the refreshing of a table view’s contents. 

If you are into a UITableViewController, you can use the refreshControl property like explained here.

But how can you use it programmatically? How can you change the tintColor? How can you change the attributeTitle color?

If you wanna use the UIRefreshControl into a UIViewController that has a UITableView inside… and if you are using iOS7… you can do it writing the code below.

How you can see, the best solution is to put the UIRefreshControl into a UIView, so the UIRefreshControl not goes under the top bar.

@interface MyViewController ()
{
    UIRefreshControl *refreshControl;
}
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
@end

@implementation MyViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *refreshView = [[UIView alloc] initWithFrame:CGRectMake(0, 55, 0, 0)];
    [self.tableView insertSubview:refreshView atIndex:0]; //the tableView is a IBOutlet

    refreshControl = [[UIRefreshControl alloc] init];
    refreshControl.tintColor = [UIColor redColor];
    [refreshControl addTarget:self action:@selector(reloadDatas) forControlEvents:UIControlEventValueChanged];
   /* NSMutableAttributedString *refreshString = [[NSMutableAttributedString alloc] initWithString:@"Pull To Refresh"];
    [refreshString addAttributes:@{NSForegroundColorAttributeName : [UIColor grayColor]} range:NSMakeRange(0, refreshString.length)];
    refreshControl.attributedTitle = refreshString; */
    [refreshView addSubview:refreshControl];
}

-(void)reloadDatas
{
    //update here...
    
    [refreshControl endRefreshing];
}

@end

That’s all.

Color-fill UIImage programmatically in iOS7

With iOS7 you can color-fill a black-transparent png file, using the imageWithRenderingMode: method and the tintColor property.

The imageWithRenderingMode: creates and returns a new image object with a specified rendering mode.
The rendering mode to use, is the UIImageRenderingModeAlwaysTemplate that draw the image as a template image, ignoring its color information.
Finally, the tintColor is the fill UIColor.

Color-fill UIImage programmatically with iOS7 | Daniele Galiotto | www.g8production.com

So, writing the code below or downloading the demo, you can color-fill your png.

UIImage *img = [UIImage imageNamed:@"smile.png"];

self.imgOriginal.image = img;

self.imgColorFill.image = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.imgColorFill.tintColor = [UIColor colorWithRed:0.98 green:0.47 blue:0 alpha:1];

Awesome!

Get property name as string, without using the runtime reference library

Go to get the name of an object property, can be boring using the Objective-C runtime reference.

Fortunately there is a quick way to get it.

Assume that you have an object named “appleStore” that has a property named “storeLocation”.

StoreLocation is another object with some properties: “city”, “lat”, “lon”, “street”, “state”, “code”.

@interface StoreLocation : NSObject

@property (nonatomic, strong) NSString *city;
@property (nonatomic, strong) NSNumber *lat;
@property (nonatomic, strong) NSNumber *lon;
@property (nonatomic, strong) NSString *street;
@property (nonatomic, strong) NSString *state;
@property (nonatomic, strong) NSString *code;

@end

@interface AppleStore : NSObject

@property (nonatomic, strong) StoreLocation *storeLocation;

@end

Since you are one of the best Objective-C developers in the world, you know that a property is composed by a keypath. So, if you wanna access to the “storeLocation” property value or to the “street” property value, you must write the code below.

AppleStore *appleStore = [AppleStore new];
//......
NSLog(@"%@", appleStore.storeLocation); //print the property value
NSLog(@"%@", appleStore.storeLocation.street); //print the property value

How you know, the keypath separator is the char “.” so, how can you print the property name???

The quick way is to define two Objective-C macros that can help you.
Just on top of your class, above the @interface declaration, write the code below.

#define propertyKeyPath(property) (@""#property)
#define propertyKeyPathLastComponent(property) [[(@""#property) componentsSeparatedByString:@"."] lastObject]

Finally, get the property name or the last component property name, using the code below in your methods.

        NSLog(@"%@", propertyKeyPath(appleStore.storeLocation)); //appleStore.storeLocation
        NSLog(@"%@", propertyKeyPath(appleStore.storeLocation.street)); //appleStore.storeLocation.street
        NSLog(@"%@", propertyKeyPathLastComponent(appleStore.storeLocation)); //storeLocation
        NSLog(@"%@", propertyKeyPathLastComponent(appleStore.storeLocation.street)); //street

That’s all.

Wait for blocks execution using a dispatch semaphore

Blocks are a language-level feature, which allow you to create distinct segment of code.

For understand how declare a block, open this link fuckingblocksyntax.com


But the question is: How do I wait for an asynchronously dispatched block to finish, in ARC?

The GCD (Grand Central Dispatch) can help us! 


The Grand Central Dispatch (GCD) comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware in iOS and OS X.

Ok, i know the GCD but how can I use it to blocks? The answer is “using semaphores”.
A dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. If the calling semaphore does not need to block, no kernel call is made.


You can “create”, “signal” or “wait” for a semaphore.

dispatch_semaphore_create => creates a semaphore with initial value
dispatch_semaphore_signal => increments the semaphore (send a semaphore signal)
dispatch_semaphore_wait => decrements the semaphore (wait for a semaphore signal)


So, you can use semaphore to wait for a blocks completion.

SINGLE BLOCK

dispatch_semaphore_t sem = dispatch_semaphore_create(0);

[self methodWithABlock:^(id result){
    //put code here
    dispatch_semaphore_signal(sem);
}];

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

MULTIPLE BLOCKS

dispatch_semaphore_t sem = dispatch_semaphore_create(0);

[self methodWithABlock:^(id result){
    //put code here
    dispatch_semaphore_signal(sem);
}];

[self methodWithABlock:^(id result){
    //put code here
    dispatch_semaphore_signal(sem);
}];

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

BLOCK IN BLOCK

dispatch_semaphore_t sem = dispatch_semaphore_create(0);

[self methodWithABlock:^(id result){
    //put code here
    dispatch_semaphore_signal(sem);
    
    [self methodWithABlock:^(id result){
        //put code here
        dispatch_semaphore_signal(sem);
    }];
}];

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

Dynamic NSCoding with Objective-C runtime and NSKeyedArchivier NSKeyedUnarchivier

The NSCoding protocol declares the two methods that a class must implement so that instances of that class can be encoded and decoded. This capability provides the basis for archiving and distribution. In other words, the basis for serialize and deserialize objects.

Use the NSCoding is easy.

Your class must implement the NSCoding protocol into the .h file. 
Into the .m you must implement the methods initWithCode: and encodeWithCoder:.

That is like below:

#import <Foundation/Foundation.h>

@interface Organism : NSObject <NSCoding>

//properties goes here

-(void)saveToDiskWithKey:(NSString *)key;
+(id)loadFromDiskWithKey:(NSString *)key;

@end
#import "Organism.h"

@implementation Organism

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
       //code goes here
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    //code gose here
}

So, using the class NSCoding, the class NSKeyedArchivier and the class NSKeyedUnarchivier, you can write and read objects into the iOS application sandbox.

Well, suppose that you have two classes with different properties. For example:

Human" with name, surname, age;

#import <Foundation/Foundation.h>

@interface Human : Organism 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *surname;
@property (nonatomic, strong) NSString *age;

@end

Cat" with name, pedigree.

#import <Foundation/Foundation.h>

@interface Cat : Organism 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *pedigree;

@end

Human and Cat inherits from a third class named “Organism”.

Without know if you are a Human or a Cat, you can encode and decode your classes, dynamically, using the Objective-c Runtime library, following the code below (Organism.m).

#import "Organism.h"
#import <objc/message.h>  //import the runtime library

@implementation Organism

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        
        unsigned int pCounter = 0;
        objc_property_t *properties = class_copyPropertyList([self class], &pCounter);
        
        for (unsigned int i = 0; i < pCounter; i++)
        {
            objc_property_t prop = properties[i];
            const char *propName = property_getName(prop);
            NSString *pUTF8 = [NSString stringWithUTF8String:propName];
            
            [self setValue:[aDecoder decodeObjectForKey:pUTF8] forKey:pUTF8];
        }

        free(properties);
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    unsigned int pCounter = 0;
    objc_property_t *properties = class_copyPropertyList([self class], &pCounter);
    
    for (unsigned int i = 0; i < pCounter; i++)
    {
        objc_property_t prop = properties[i];
        const char *propName = property_getName(prop);
        NSString *pUTF8 = [NSString stringWithUTF8String:propName];
        
        [aCoder encodeObject:[self valueForKey:pUTF8] forKey:pUTF8];
    }
    
    free(properties);
}

It will encode and decode your properties using their names. Amazing!!

So now you can read and write your encoded classes from and to the disk, using two custom methods (have you seen saveToDiskWithKey: and loadFromDiskWithKey: above??), into the Organism.m class:

#import "Organism.h"
#import <objc/message.h>  //import the runtime library

@implementation Organism

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        
        unsigned int pCounter = 0;
        objc_property_t *properties = class_copyPropertyList([self class], &pCounter);
        
        for (unsigned int i = 0; i < pCounter; i++)
        {
            objc_property_t prop = properties[i];
            const char *propName = property_getName(prop);
            NSString *pUTF8 = [NSString stringWithUTF8String:propName];
            
            [self setValue:[aDecoder decodeObjectForKey:pUTF8] forKey:pUTF8];
        }

        free(properties);
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    unsigned int pCounter = 0;
    objc_property_t *properties = class_copyPropertyList([self class], &pCounter);
    
    for (unsigned int i = 0; i < pCounter; i++)
    {
        objc_property_t prop = properties[i];
        const char *propName = property_getName(prop);
        NSString *pUTF8 = [NSString stringWithUTF8String:propName];
        
        [aCoder encodeObject:[self valueForKey:pUTF8] forKey:pUTF8];
    }
    
    free(properties);
}

-(void)saveToDiskWithKey:(NSString *)key
{
	NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
	[[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
	[[NSUserDefaults standardUserDefaults] synchronize];
}

+(id)loadFromDiskWithKey:(NSString *)key
{
	NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:key];
	id result = [NSKeyedUnarchiver unarchiveObjectWithData:data];
	return result;
}

That’s all!

You are ready to load and save Human and Cat:

Human *human = [Human loadFromDiskWithKey:@"thehuman"];
[human saveToDiskWithKey:@"thehuman"];

Cat *cat = [Cat loadFromDiskWithKey:@"thecat"];
[cat saveToDiskWithKey:@"thecat"];

iOS7 Multitasking: Silent notifications

Yet another multitasking post.

An iOS7 App now can works in background mode using:

- Background fetch
- Silent notifications
- Background transfer service.

Today i will explain how to use the Silent notifications:

iOS7 can helps us to update an App, using a remote and silent notification.

So, when iOS7 receives a silent notification, it wakes up the App and update the content of her.

A silent notification, if not used in conjunction with a push notification, is not visible to the user.

You can enable silent notifications in XCode5, going to the project/capabilities and enabling Background Modes and the Remote notifications option.



iOS7 Multitasking Remote Silent Notifications | Daniele Galiotto | www.g8production.com | speaker Mokapp 2013


Please enable only options that you will use else Apple will refuse your app!

Great! What is a silent notification?
A silent notification is a remote notification, like a push notification. It’s JSON based and you can send a silent notification in conjunction with a push notification too.


Step one
: configure the APN service and the app to receive remote notifications. You can use the parse service for this.
Parse is the best way to use and send remote notifications (iOS Parse notification tutorial).

With Parse you can send remote notifications using the JSON format. So, you can send a push notification, a silent notification or a push-and-silent notification, writing the correct JSON.

A push notification has a format like below:

{
    "aps" : {
        "alert" : "YAP",
        "badge" : 2,
        "sound" : "sound.aiff"
    }
}

a silent notification has a format like below:

{
    "aps" : {
        "content-available" : 1,
        "sound" : ""
    }
}

How you can see, the key “content-available” is the key that enable a silent notification.

Warning! When you send a silent notification with the Parse service, you must send the sound key too, else the silent notification can be not works.


Step two
: configure the App to receives silent notifications.

Into the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method, register the App for remote notifications, writing the code below. 

[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

This is the same step required for silent and push notifications.

Warning
! Don’t forget that the iOS Simulator can’t receives remote notifications!!! You must use a physical device!


Step three
: in the AppDelegate implement the method -application:didReceiveRemoteNotification:fetchCompletionHandler:

Inside write your code. For example you can call a REST service to receive last news. 

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    if([userInfo[@"aps"][@"content-available"] intValue]== 1) //it's the silent notification
    {
        //bla bla bla put your code here
        completionHandler(UIBackgroundFetchResultNewData);
        return;
    }
    else
    {
        completionHandler(UIBackgroundFetchResultNoData);
        return;
    }
}


Don’t forget that:

- you must update the user interface (using the main thread!)

- you can advise the user with a badge icon or/and a local notification when the update is completed.

- the method must return a UIBackgroundFetchResult
    UIBackgroundFetchResultNewData if the app has downloaded new datas
    UIBackgroundFetchResultNoData if the are not new datas
    UIBackgroundFetchResultFailed if there is a error

- the fetch request has 30 seconds of limit so you not use it to download big data (the Background Transfer Service is the correct way. You can use it in conjunction with the Silent Notification).

- Not abuse!

- Silent notifications can be received with delay.

- A lot of silent notifications can be received all together, using a queue.


Finally, run the app into the iPhone and send a silent notification with Parse (or your APN Service).

To send a silent notification with Parse, go to Push Notifications tab, enable JSON in the Compose Message section, put there the code below and send the notification:

{ "content-available": 1, "sound": ""}

That’s all. Have a nice debug!


You can download a demo here (it includes Background Fetch and Background Transfer Service too).