Universal Linking for your iOS App

Despite of Deep Linking, Universal links can link a website domain with your mobile app without using any redirection on website. Your users can go through your app by clicking a https url, directly. (Directly, means your users don’t go Safari before opening of your application.) But how? iOS operation system can link mobile applications with domains. A mobile application can be link up to 30 domains.

To do so:

  • You need to create a contract file (in json format) that stores mobile app information on server side. (You need to specify )
  • Put this apple-app-site-association file under .well-known directory. You can this on Safari, by typing url https://DOMAIN_URL/apple-app-site-association . If you can reach this file, everything is OK and you’re ready to continue configurations on mobile project side.
  • Turn of Associate domains for your application. This will create an entitlement file and you need to update your provisioning profile. If you’re using Continuous Integration.

Read More »

Advanced Permission Management for iOS Applications

Mobile applications ask permissions to access user’s information or user’s phone features. These permissions can be accessing camera, microphone, location, phone contact list, calendars, photos, reminders etc.

You should define your permission asking strategy wisely. You can prefer either asking permission right before using this-exact feature or you can show information why you really need these permissions and direct your users to your application’s settings page or both. If a user will not continue using your app without giving permissions, it’s nice to show information why you need it and what your application offers the user by using these features, then direct users your application settings page.Read More »

How to add Core Spotlight to index your app content on iOS9? (ADVANCED)- iOS9 Feature (Part 4)

I’ve mentioned about “How to add Core Spotlight to index your app content on iOS9?” in this article. If you haven’t read it, I really recommend you do.

This article will be about how to add multiple search item in very little and efficient code writing. Search items have some features such as title, contentDescription, rating, unique identifier , thumbData which will show the icon of your special content or basically your application, and so on.

Basically there are two advanced concepts you should know about CSSearchableItems / CoreSpotlight.

First one is your user can navigate anywhere in your app, by understanding which search item is tapped by your user in Spotlight. You can be sure of your users will find anything they search, by navigating them true navigation point of application.

Apple serves very basic app delegate method :

– (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler;

Second one is that you can list your search items and their attributes in a very simple but handy property list (plist) file and creating a very simple singleton class you can call it SearchManager, will help you to separate your search methods from other app delegate methods.

Screen Shot 2016-01-18 at 21.36.06

Soo, let’s start!

In delegate of your application, you should call your SearchManager for initializing to index searchable items at spotlight.


- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
   [[SearchManager sharedInstance] initializeSpotlightSearch];
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler{

   if([userActivity.activityType compare: @"com.apple.corespotlightitem"]== NSOrderedSame){
      [[SearchManager sharedInstance] navigateFromSpotlightSearchItemContinueUserActivity:userActivity];
return YES;


You can find a brief explanation for following SearchManager code for Spotlight search.

#import "SearchManager.h"

@implementation SearchManager

static SearchManager *sharedInstance = nil;

NSString *const UNIQUE_IDENTIFIER_KEY       = @"uniqueIdentifier";
NSString *const DOMAIN_IDENTIFIER_KEY       = @"domainIdentifier";
NSString *const TITLE_KEY                   = @"title";
NSString *const CONTENT_DESCRIPTION_KEY     = @"contentDescription";
NSString *const THUMBNAIL_DATA_KEY          = @"thumbnailData";
NSString *const NAVIGATION_URL_KEY          = @"navigationURL";
NSString *const KEYWORDS_KEY                = @"keywords";
NSString *const KEYWORD_KEY                 = @"keyword";

+ (SearchManager *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[super allocWithZone:NULL] init];
    return sharedInstance;

//You should check if application is running iOS9 + devices,
//Otherwise your application will crash on iOS7 or iOS8 devices. 

        NSMutableArray *searchableItemList = [self getCSSearchableItemList];
        CSSearchableIndex *defaultSearchableIndex = [CSSearchableIndex defaultSearchableIndex];
        [defaultSearchableIndex indexSearchableItems:searchableItemList completionHandler:^(NSError * _Nullable error) {
            if (error)
                DLog(@"print error: %@", error.description);
                DLog(@"indexed successfully");

+ (NSDictionary *)getPropertyFileBySource:(NSString *)source andRoot:(NSString *)root {
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *plistPath = [bundle pathForResource:source ofType:@"plist"];
    NSDictionary *serachableItemsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
    return serachableItemsDictionary[root];

-(NSDictionary*) getSearchableItemsPlistDictionary{
    return [SearchManager getPropertyFileBySource:@"SearchableItems" andRoot:@"spotlightSearchItems"];
- (NSMutableArray*)getCSSearchableItemList{
    NSDictionary *searchableItemsClientDictionary = [self getSearchableItemsPlistDictionary];
    return [self getCSSearchableItemList:searchableItemsClientDictionary];

- (NSMutableArray*)getCSSearchableItemList:(NSDictionary *)searchableItemsClientDictionary {
    NSMutableArray *searchableItemList = [[NSMutableArray alloc]init];
    for (NSString *searchableItemDictKey in [searchableItemsClientDictionary allKeys]) {
        NSDictionary *searchableItemDict = [searchableItemsClientDictionary objectForKey:searchableItemDictKey];
        NSString *uniqueIdentifier=[searchableItemDict objectForKey:UNIQUE_IDENTIFIER_KEY];
        NSString *domainIdentifier=[searchableItemDict objectForKey:DOMAIN_IDENTIFIER_KEY];
        NSString *contentDescription=[searchableItemDict objectForKey:TITLE_KEY];
        NSString *displayName=[searchableItemDict objectForKey:CONTENT_DESCRIPTION_KEY];
        NSString *title=[searchableItemDict objectForKey:TITLE_KEY];
        NSString *thumbnailData=[searchableItemDict objectForKey:THUMBNAIL_DATA_KEY];
        NSDictionary *keywords = [searchableItemDict objectForKey:KEYWORDS_KEY];
        NSMutableArray *keywordsArray = [[NSMutableArray alloc]init];
        for (NSString *akeywordKey in [keywords allKeys]) {
            [keywordsArray addObject:keywords[akeywordKey]];
        CSSearchableItemAttributeSet *searchableItemAttributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:uniqueIdentifier];
        searchableItemAttributeSet.contentDescription = contentDescription;
        searchableItemAttributeSet.title = title;
        searchableItemAttributeSet.displayName = displayName;
        searchableItemAttributeSet.keywords = keywordsArray;
            UIImage *thumbnail = [UIImage imageNamed:@"AppIcon"];
            searchableItemAttributeSet.thumbnailData = UIImageJPEGRepresentation(thumbnail, 0.7);
        CSSearchableItem *searchableItem = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifier
        [searchableItemList addObject:searchableItem];
    return searchableItemList;

-(NSString*) getNavigationURLForSearchableItemKey:(NSString*)searchableItemKey{
    NSDictionary *searchableItemsClientDictionary = [self getSearchableItemsPlistDictionary];
    NSDictionary *searchItem = searchableItemsClientDictionary[searchableItemKey];
        return (NSString*)searchItem[NAVIGATION_URL_KEY];
    return @"";
-(void) navigateFromSpotlightSearchItemContinueUserActivity:(NSUserActivity *)userActivity{
    NSDictionary *searchUserInfo = userActivity.userInfo;
    NSString *activityIdentifier = searchUserInfo[CSSearchableItemActivityIdentifier];
  //  NSString *activityType = searchUserInfo[CSSearchableItemActionType];
    NSString *navigationURL = [self getNavigationURLForSearchableItemKey:activityIdentifier];
        // To do - write your codes for navigation, here.

If you don’t want to navigate the spesific point at your application. You can ignore these following methods.
-(void) navigateFromSpotlightSearchItemContunieUserActivity:(NSUserActivity*)userActivity;
-(NSString*)getNavigationURLForSearchableItemKey:(NSString*) searchableItemKey;

PS: If you find this article useful please use like button 🙂 and if you have a question or a comment, don’t hesitate to share it!

May the Force Touch be with you! 🙂 

Apple’s brand new system font, San Francisco!

After using SF font on Apple watch, Apple decided to use San Francisco font as the default font on iPhone/iPad devices with iOS9 too.

What are the differences between Helvetica Neue and San Francisco?

Well… All of us knows that Apple is very keen on working about having good fonts, bringing great typography for Apple devices. San Francisco fonts are more readable, especially if you’re using San Francisco Display family. But Helvetica Neue and San Francisco look more or less alike.

Screen Shot 2015-12-29 at 22.53.24.pngScreen Shot 2015-12-29 at 22.57.15Helvetica Neue and San Francisco Text respectively..Read More »

How to add Core Spotlight to index your app content on iOS9? – iOS9 Feature (Part 4)

Apple Says That;

When you make your content searchable, users can access activities and content deep within your app through Spotlight and Safari search results, Handoff, and Siri suggestions.

Point of an developer’s view, main aim of content indexing on iOS9 is to help you make your content available in the appropriate index, drive user engagement and maybe free marketing :D.Read More »

After Fabric IO upgrade, what did I experience in Jenkins build server?

And .. What did I learn about this process?

Upgrading Crashlytics to Fabric IO framework, is not very painful at all, unless you don’t use Jenkins build server for your build. In automated builds, I did stuck in situation like dSYM files weren’t uploaded automatically in every build.

So what are dSYM files ?

dSYM files store the debug symbols for your app. Services like Crashlytics uses these files to replace the symbols in the crash logs with the appropriate methods names, so it will be readable and will make sense.Read More »

Implementing Home Screen Quick Actions, Dynamic shortcutItems – iOS9 Feature (Part 3)

My previous post was for giving  the general information on implementing home screen quick actions by the way of using static shortcut items in the info.plist of project. To read general concept and methods, this way please.

Despite of the static shortcut items can not be changed regarding to different cases, dynamic shortcut items can be changed case by case in any wherever or whenever in application running cycle. Read More »

How to implement Peek and Pop & show previewActionItems- iOS9 Feature (Part 2)

“Peek and Pop” is one of the great feature of 3D Touch. In my previous post I mentioned about “Home Screen Quick Actions” and adopting force touch, you can check this article here.
Peek And Pop feature allows users to preview a content (peek) with force touch and the content is opened in full size (popwith one more gentle move which keeps the previous touch up.Read More »