Search Your Question

Optional, Optional Binding, Unwrapping and Optional Chaining

Ans : 

Optional : Optional is swift's powerful feature which come to solve problem of  non-existing value. It is just a type . There are two types as Int (which must has a value) and Int?(which may contain a Int value or may have nil value). It is declared as T? i.e Int?, String?

Forced Unwrapping : Exclamation mark ( ! ) is used to unwrap value.
i.e let optionalInt : Int? = 5
let intVal : Int = 2
optionalInt! + intVal

So we hvae forecfully unwrap optionaInt. That means we tell compiler that optionalInt has a value and extract and use it.

But this is not good practise. If sometimes optionaInt has not value and we try to unwrap, then app will be crashed. A good practise is to check with nil before unwrapping or use optional binding. It checks it has value or not and if and only if it has value extract it and use it.

Optional Binding : You use optional binding to check if the optional contains a value or not. If it does contain a value, unwrap it and put it into a temporary constant or variable.

Example :

var stockCode:String? = findStockCode("Facebook")

let text = "Stock Code - "

if let tempStockCode = stockCode {

    let message = text + tempStockCode

    println(message)
}

The “if let” (or “if var”) are the two keywords of optional binding. In plain English, the code says “If stockCode contains a value, unwrap it, set its value to tempStockCode and execute the conditional block. Otherwise, just skip it the block”. As the tempStockCode is a new constant, you no longer need to use the ! suffix to access its value.

Implicitly Unwrapped Optional : When we are very very sure about it has value after first time it is set, then we need not unwrap every time. So for this type of scenario, we have to use it with ! mark in their type.

// forced unwrapping
let optionalInt: Int? = 123
let forcedInt: Int = optionalInt!

// implicitly unwrapped optional
let assumedInt: Int! = 123
let implicitInt: Int = assumedInt

It may has nil value.

Optional Chaining :

The feature allows us to chain multiple optionals together with the “?.” operator.


if let sharePrice = findStockCode("Apple")?.price {

    let totalCost = sharePrice * 100

    println(totalCost)

}

FindstockCode method returns optional value. We can access multiple optional together using Optional chaining feature.

Dynamically set UITableview cell height

Ans : 

For auto cell height in tableview in Swift 3.0

Write following 2 lines of code in viewDidLoad and before reload tableview :

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44

Following steps must to do otherwise label height will not be increase and so UITableiViewCell.

Label height must be auto incremented using numberOfLines = 0

LineBreak should be set according your need word-wrap, char-wrap, etc...

ARC - Automatic Reference Counting

Ans : Automatic Reference Counting is memory management feature in iOS that provides automatic referencing counting system. According to attribute type of property like retain and release, it increment and decrements reference count at runtime.

ARC is does not handle reference cycle automatically. 

Unlike garbage collection, ARC does not handle reference cycles automatically.


Default property attributes : 

i> Memory management : strong  weak  copy  assign 
ii> Thread Safety : atomic nonatomic
iii> Mutability : readwrite readonly

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

For IBOutlet,

@property (nonatomic, retain) IBOutlet UILabel *label;


@property (weak) IBOutlet UILabel *instructions;
In 2015, apple recommend to use Strong.


To stop retain cycle, user should mention weak reference when needed.

Q : What is retain?
A.Retain works same as Strong according to apple document. If we assign retain, it will convert to strong or consider as Strong. 

Read : Difference between Strong and Weak attribute

Difference between Swift and Objective C

Ans : 

1. Swift is easier to read :

Swift removes @ symbol which exists in objective C.
Swift removes also legacy convention like semicolon at end of  statement.
Swift's method and function are easily called and [[ ]] are removed which exists in Objective C.

2. Swift is easier to maintain :

There are only 1 file to maintain name.swift. In objective c, there are .h and .m file for one viewcontroller or any views. So in swift, we have to maintain less files.

3. Swift is safe :

Optional type make the possibility of nil value very clearly, which means it generate compiler error as you write bad code instead of run time. So it reduce programmer's time due to not run the program for checking and resolve it after error coming run time.

4. Swift is robust in memory management :

ARC is available in Objective C but it supports only for Cocoa API and object oriented code. It does not support for procedural C code and Core Graphics API. So its programmer responsibility to mange memory. So it may have memory leak issue. Swift supports ARC for both procedural and object orientated code.

5. Swift less code :

+ sign concatenate two string in swift.
No need to remember value type token as %d, %s, %c like objective C. Swift does not require this type of token.

6. Swift is faster :

7. Swift supports dynamic library :

iOS doesn't support dynamic library untill released of swift and iOS 8.

8. Swift has playground :

Useful when programmar want to test 5 to 10 lines of code, he can test on playground instead of creating new application.






Multi threading, GCD, Operation Queue

Ans : 

1.
Thread : It is lightweight way to implement multiple paths of execution inside of an application.

2. Multi threading : iPhone CPU can only perform one operation at a time – once per clock cycle. Multi threading allows the processor to create concurrent threads it can switch between, so multiple tasks can be executed at the same time.

It appears as if the two threads are executed at the same time, because the processor switches rapidly between executing them. As a smartphone or desktop user, you don’t notice the switches because they occur so rapidly.

Multi threading allows a CPU to rapidly switch between multiple tasks in such a way that it appears as if the tasks are executed simultaneously.

You can’t update an app’s UI outside the main thread.

Race Condition  A race condition occurs when two tasks are executed concurrently, when they should be executed sequentially in order to be done correctly. You cant change view constraint while it is being calculated. So UI activity should be done in main thread so it is executed sequentially.


3. GCD : Grand Central Dispatch is a wrapper around creating threads and managing that code. Its emphasis is on dispatching. The Grand Central Dispatch (GCD) is a is a low-level API provided by Apple. GCD is used for managing concurrent operations. GCD has lots of benefits like

– It improves application performance and responsiveness.
– The app will become more smooth.
– Execute multiple tasks at a time or one by one as per your requirements.
GCD operates at the system level, it is managing the resources in a balanced way for all running application.



GCD & Operation Queues help keep your app user interface responsive by running slow task of main queue.

low_level_C coding :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    // Download file or perform expensive task

    dispatch_async(dispatch_get_main_queue()) {
        // Update the UI
    }
}

Swift 3+ code :

DispatchQueue.global(qos: .userInitiated).async {
    // Download file or perform expensive task

    DispatchQueue.main.async {
        // Update the UI
    }
}

There are 4 qos - quality of service level (Priority) from higher to low :

.userInteractive,
.userInitiated,
.utility
.background.

Learn more about QOS

For delaying task :

let delay = DispatchTime.now() + .seconds(60)
DispatchQueue.main.asyncAfter(deadline: delay) {
    // Dodge this!
}

Multi threading, GCD, Operation Queue

Ans : 

1.
Thread : It is lightweight way to implement multiple paths of execution inside of an application.

2. Multi threading : iPhone CPU can only perform one operation at a time – once per clock cycle. Multi threading allows the processor to create concurrent threads it can switch between, so multiple tasks can be executed at the same time.

It appears as if the two threads are executed at the same time, because the processor switches rapidly between executing them. As a smartphone or desktop user, you don’t notice the switches because they occur so rapidly.

Multi threading allows a CPU to rapidly switch between multiple tasks in such a way that it appears as if the tasks are executed simultaneously.

You can’t update an app’s UI outside the main thread.

Race Condition  A race condition occurs when two tasks are executed concurrently, when they should be executed sequentially in order to be done correctly. You cant change view constraint while it is being calculated. So UI activity should be done in main thread so it is executed sequentially.


3. GCD : Grand Central Dispatch is a wrapper around creating threads and managing that code. Its emphasis is on dispatching.

low_level_C coding :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    // Download file or perform expensive task

    dispatch_async(dispatch_get_main_queue()) {
        // Update the UI
    }
}

Swift 3+ code :

DispatchQueue.global(qos: .userInitiated).async {
    // Download file or perform expensive task

    DispatchQueue.main.async {
        // Update the UI
    }
}

There are 4 qos - quality of service level (Priority) from higher to low :

.userInteractive,
.userInitiated,
.utility
.background.

For delaying task :

let delay = DispatchTime.now() + .seconds(60)
DispatchQueue.main.asyncAfter(deadline: delay) {
    // Dodge this!
}

4. Operation Queue : 

Operations in Swift are a powerful way to separate responsibilities over several classes while keeping track of progress and dependencies. They’re formally known as NSOperations and used in combination with the OperationQueue.

An Operation is typically responsible for a single synchronous task. It’s an abstract class and never used directly. You can make use of the system-defined BlockOperation subclass or by creating your own subclass. You can start an operation by adding it to an OperationQueue or by manually calling the start method. However, it’s highly recommended to give full responsibility to the OperationQueue to manage the state.

//Making use of the system-defined BlockOperation looks as follows:

let blockOperation = BlockOperation {
    print("Executing!")
}

let queue = OperationQueue()
queue.addOperation(blockOperation)
//And can also be done by adding the block directly on the queue:

queue.addOperation {
  print("Executing!")
}

//The given task gets added to the OperationQueue that will start the execution as soon as possible.

Different states of an operation
An operation can be in several states, depending on its current execution status.
  • Ready: It’s prepared to start
  • Executing: The task is currently running
  • Finished: Once the process is completed
  • Canceled: The task canceled


What is subclassing?

Ans : Subclassing is way of inheriting property of one class to another class. Child class inherit all behaviour of parent class. Let's talk about UIImageView.

NSObject > UIResponder > UIView > UIImageView

I have made one class as SpecialImageView which inherit UIImageView.  So SpecialImageView is subclass and UIImageView is parent class.

Suppose I want  5 imageview in my viewcontroller, which has default behaviour like borderWidth =2, broderColor = blue. 

So I have written this behaviour in SpecialImageView class once. All those 5 images are as SpecialImageView instead of UIImageView. 

So I do not need to write to all this behaviour for every 5 imageviews. So subclassing gives benefit of customisation of any class.


When we want custom UITableViewCell then we need to make subclass of UITableViewCell.

Difference between == and ===

Ans :  == checks equality and === checks identity. == check value of left side and right side are same or not. === check left side object and right side object point to same memory or not.

== used against int, float, string (value type) and === used against reference type (class type).

i.e

class SomeClass {
var a: Int;

init(_ a: Int) {
    self.a = a
}

}

var someClass1 = SomeClass(4)
var someClass2 = SomeClass(4)
someClass1 === someClass2 // false
someClass2 = someClass1
someClass1 === someClass2 // true

Explain Apple push notification working

Ans : Push notifications allow developers to reach users and perform small tasks even when users aren’t actively using an app.

In iOS 10, User can do following task :

  • Display a short text message
  • Play a notification sound
  • Set a badge number on the app’s icon
  • Provide actions the user can take without opening the app
  • Show a media attachment
  • Be silent, allowing the app to wake up in the background and perform a task
Now following steps to follow to configure push notification :

1. Create app id in developer account with your app bundle id. Push notification entitlement must be enabled for this app id. (or another way for go to App Settings > Capabilities and enable push notification switch). You also have to create CSR(Certificate Signing Request) file from your keychain and assign to this app id push notification feature in developer account.

2. Now in terms of coding, first we need to ask to user for allowing user notification. After allowing, we need to register for remote notification. If all goes good, system provides you 'token' which is address of this app for this device.

3. In code, first import usernotification. Then for registering for remote notification, in didFnishLaunchingWithOptions

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])  {
    (granted, error) in
   
       print("Permission granted: \(granted)")
    
       guard granted else { return }
       self.getNotificationSettings()

  }

 func getNotificationSettings()  {
       UNUserNotificationCenter.current().getNotificationSettings { (settings) in
       print("Notification settings: \(settings)")
       guard settings.authorizationStatus == .authorized else { return }
       UIApplication.shared.registerForRemoteNotifications()
  }


4. If registered for remote notification successfully, then one of the following two method will be called,

func application(_ application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)  {

       let tokenParts = deviceToken.map { data -> String in
              return String(format: "%02.2hhx", data)
        }

       let token = tokenParts.joined()
       print("Device Token: \(token)")
}

func application(_ application: UIApplication,
                 didFailToRegisterForRemoteNotificationsWithError error: Error)  {
  print("Failed to register: \(error)")
}

5. Device token is provided by APNS and this token will be converted to string. This device token shold be sent to application server or stored to database on server side.

Now lets study about payload or notification message,

Payload looks like :

{
  "aps": {
    "alert": "Breaking News!",
    "sound": "default",
    "link_url": "https://raywenderlich.com"
  }
}

aps is fixed key in payload dictionary json. aps is also dictionary itself.

alert : Display text message
sound : Which sound when notification come
link_url : custom key, we can any such custom key for data
badge : number of count of badge that is displayed on app icon
category : which type of custom action notification have

Payload maximum size is 4096 kb (4 mb).


Now what when notification comes

1. If app is closed didFinishLaunchingWithOptions is called.
2. If open in background or foreground, then didReceiveRemoteNotification is called.

For 1st case,

In didFinishLaunchingWithOptions method
// Check if launched from notification

if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject] {

  let aps = notification["aps"] as! [String: AnyObject]
  _ = NewsItem.makeNewsItem(aps)

  (window?.rootViewController as? UITabBarController)?.selectedIndex = 1
}

For 2nd case,

In didReceiveRemoteNotification,

let aps = userInfo["aps"] as! [String: AnyObject]
  _ = NewsItem.makeNewsItem(aps)

Actionable Notification

Actionable notifications let you add custom buttons to the notification. You can put reply,retweet,like button as you seen our favourite apps. This type of notification can be defined by Category.

In this type notification, we have to register category like following instead of UIApplication.shared.registerForRemoteNotifications().

func registerForPushNotifications() {
  UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
    (granted, error) in   
    print("Permission granted: \(granted)")
 
    guard granted else { return }
 
    // 1
    let viewAction = UNNotificationAction(identifier: viewActionIdentifier,
                                          title: "View",
                                          options: [.foreground])
 
    // 2
    let newsCategory = UNNotificationCategory(identifier: newsCategoryIdentifier,
                                              actions: [viewAction],
                                              intentIdentifiers: [],
                                              options: [])
    // 3
    UNUserNotificationCenter.current().setNotificationCategories([newsCategory])
 
    self.getNotificationSettings()
  }
}


Above things is not enough for taking action on button. We have to add extension of UNUserNotificationCenterDelegate.

Silent Notification 

If we want to do something task without knowing to user in background, then we can send silent notification to user device. For this background modes of push notification must be checked. For push notification aps, there is key named content-available. That's value should be 1 for silent notification.

For more detail, click here.



How to find current location?

Ans : 

Framework : MapKit
Class : CLLocationManager
Delegate : CLLocationManagerDelegate

Write NSLocationAlwaysUsageDescription and also its description in info.plist file.

Code :

@IBAction func setCurrentLocation(sender: AnyObject) {
        if CLLocationManager.locationServicesEnabled() {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest

            if self.locationManager.respondsToSelector(#selector(CLLocationManager.requestAlwaysAuthorization)) {
                locationManager.requestAlwaysAuthorization() // request for authorisation for first time when app open
            } else {
                 locationManager.startUpdatingLocation()
            }
        }
    }


 //Updated location

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

//Get last updated location(current)

        let location = locations.last! as CLLocation

        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)

        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.20, longitudeDelta: 0.20))

//Set region of current location in map view with zooming

        self.mpView.setRegion(region, animated: true)

//Show current location (blue dot) on map
        self.mpView.showsUserLocation = true

    }