Interviews for an iOS Developer??

If you’re looking for a nice developer job, first thing you should check is your basic programming knowledge, of course. Or maybe, you are not looking for new opportunities. –> You just don’t want to lose flexibility of programming skills on a specific language or algorithm know-how. Best thing you can do is simply EXERCISING.

There are several websites you can use to solve programming problems on different areas (such as Data Structures, Algorithms, AI, Databases or Security) by using different programming languages. (From Python, Go, ADA to Swift) These websites are really good for improving whiteboard coding skills.Read More »

What happened to Macros in Swift? Using Xcconfig files and Custom Flags for Clean Project Settings

Macros were cool, they are already cool for Objective-C developers. (If you have an Objective-C project, this article is for you.) But in Swift, you should choose a different way to manage your project configurations. Because they are not available anymore.

But we have other cool things like xcconfig files and custom flags.

1 – Lets start with Config files…

You can use config files to define project variables and set different values for these variables under different project schemes.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 »

Build Your Own Framework

Coding is like playing with legos. There are so many cases that you can -and probably you should- use same lego piece for different structures, multiple times.

“If the code appears more than once, it probably belongs in a framework.” WWDC14

Apple introduced Cocoa Touch Frameworks in 2014 – the same year as iOS8 is launched . If you haven’t watched yet, I strongly recommend you to watch Building Modern Frameworks session.

Frameworks are best way to reuse your code and share with multiple projects. For instance, @Apple Health app has its own framework – HealthKit – and other developers can use HealthKit.framework by linking it with their projects.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
SearchableItems.plist

Soo, let’s start!

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

APPDELEGATE.

- (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;
}

SearchManager.

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;
}

-(void)initializeSpotlightSearch{
//You should check if application is running iOS9 + devices,
//Otherwise your application will crash on iOS7 or iOS8 devices. 
    if(IS_IOS9_OR_GREATER){

        NSMutableArray *searchableItemList = [self getCSSearchableItemList];
        
        CSSearchableIndex *defaultSearchableIndex = [CSSearchableIndex defaultSearchableIndex];
        [defaultSearchableIndex indexSearchableItems:searchableItemList completionHandler:^(NSError * _Nullable error) {
            if (error)
                DLog(@"print error: %@", error.description);
            else
                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;
        if(IsEmpty(thumbnailData)){
            UIImage *thumbnail = [UIImage imageNamed:@"AppIcon"];
            searchableItemAttributeSet.thumbnailData = UIImageJPEGRepresentation(thumbnail, 0.7);
        }
        
        CSSearchableItem *searchableItem = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifier
                                                                             domainIdentifier:domainIdentifier
                                                                                 attributeSet:searchableItemAttributeSet];
        
        [searchableItemList addObject:searchableItem];
        
    }
    return searchableItemList;
}

-(NSString*) getNavigationURLForSearchableItemKey:(NSString*)searchableItemKey{
    NSDictionary *searchableItemsClientDictionary = [self getSearchableItemsPlistDictionary];
    NSDictionary *searchItem = searchableItemsClientDictionary[searchableItemKey];
    if(!IsEmpty(searchItem)){
        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];
    if(!IsEmpty(navigationURL)){
        // 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! 🙂 

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 »

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 »