Search Your Question

What is UIResponder Chain?

Ans : 

Apps receive and handle events using responder objects. A responder object is any instance of the UIResponder class, and common subclasses include UIView, UIViewController, and UIApplication. UIKit manages most responder-related behavior automatically, including how events are delivered from one responder to the next.

Example : 

For every event, UIKit designates a first responder and sends the event to that object first. The first responder varies based on the type of event. 

UIKit uses view-based hit testing to determine where touch events occur. Specifically, UIKit compares the touch location to the bounds of view objects in the view hierarchy. The hitTest:withEvent: method of UIViewwalks the view hierarchy, looking for the deepest subview that contains the specified touch. That view becomes the first responder for the touch event. 

If a touch location is outside of a view’s bounds, the hitTest:withEvent: method ignores that view and all of its subviews. As a result, when a view’s clipsToBounds property is NO, subviews outside of that view’s bounds are not returned even if they happen to contain the touch.

UIResponder Chain
  • If the view is the root view of a view controller, the next responder is the view controller. 
  • If the view is not the root view of a view controller, the next responder is the view’s superview. 
  • If the view controller’s view is the root view of a window, the next responder is the window object. 
  • If the view controller was presented by another view controller, the next responder is the presenting view controller. 
  • UIWindow. The window’s next responder is the application object. 
  • UIApplication. The app object’s next responder is the app delegate, but only if the app delegate is an instance of UIResponder and is not a view, view controller, or the app object itself.

What is capture and capture list in closure?

Ans :

According to apple document :

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages. 

Closures can capture and store references to any constants and variables from the context in which they are defined. This is known as closing over those constants and variables. Swift handles all of the memory management of capturing for you.

Closure is reference type

Capturelist is used to stop memory leakage.

Code for Example of memory leakage :


class Increment {
    var number = 0

     deinit {
        print(#function)
    }
    
    lazy var incrementNumber: (Int) -> () = { value in
        self.number += value
        print(self.number)
    }
}

 do {
  let increment = Increment()

  increment.incrementNumber(3
 }


This will cause memory leak, the closure refers back to the object itself, it refers to self in order to increment the number, and that will create a reference cycle:

We have an object and the object has a stored property that refers to a closure.
That closure refers back to self (means Increment instance)

In above example, deinit should be called. But it never due to retain cycle created.

To Stop memory leakage we use capture list :

1. [unowned self]
2. [weak self]
3. [strong self] - Default

1.

lazy var incrementNumber: (Int) -> () = { [unowned self] value in
        self.number += value
        print(self.number)

    }

If I use [unowned self] there here less chance to crash. But if we use
let increment = Increment().incrementNumber(3)
then there will be more chance to be crashed. We can not immediately call incrementNumber method after object instantiated. Because when the stored property has returned, the object (increment instance) can be deallocated, nothing else is referring to it.

2.

 let’s change [unowned self] to [weak self], that means that everywhere that self is accessed, we treat it as a weak property. While using weak, we should use optional self? to access property.

When the stored property has returned, if the object be deallocated, mean self is nil, then the number will not be incremented. This code will make it easy to handle if self is nil

So when no clue to what to use, we should use [weak self] as capture list.





What is AutoReleasePool?

Ans : 

In simple word, it is pool contained objects that will be released in some time.

Object's retain and release is constant action on object. For that Retain() and Release() methods called in objective c to control memory flow. As iOS objects work on retain count concept, it tells retain counts and it will be released if it reaches to 0.

Sometimes, we can not continuously use Release() method to release object.

Code for example :

 -(NSString *)getCoolLabel {
    NSString *label = [[NSString alloc] initWithString:@"SwiftRocks"];
    [label release];
    return label;
 }

    

Here label has 2 retain count and after return it has 1 retain count. It will be in memory as we can not execute release after return label; statement.

So solution :
return [label autorelease];
It will not release label instantly, but it inserts label in pool, and in some time, when autorelease pool thread execute, it

Note : Instead of instantly reducing the retain count of an object, autorelease() adds the object to a pool of objects that need to be released sometime in the future, but not now. By default, the pool will release these objects at the end of the run loop of the thread being executed, which is more than enough time to cover all usages of getCoolLabel() without causing memory leaks.

Whatever code that takes much memory we can add in autoreleasepool block.
I.e

@autoreleasepool {
           NSString *contents = [self getFileContents:files[i]];
           NSString *emojified = [contents emojified];
           [self writeContents:contents toFile:files[i]];

       }

Above all code written in objective - c, but in swift AutoReleasePool is required?

Yes, it depends on code.  It’s a different story if your code is dealing with legacy Obj-C code, specially old Foundation classes in iOS.

To put it short, autoreleasepool is still useful in iOS/Swift development as there are still legacy Obj-C classes in UIKit and Foundation that call autorelease, but we not have to worry where there is pure swift code.



What is Generics in Swift? Write a program to make and use generics.

Ans :

Apple doc says: Generic code enables you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication by using generics in most cases.

Code for Example :


 let intArray = [1,2,3,4,5] // type int
 let stringArray = [“abhi”, “iOS”] // type string



If we want to print all values, we have to make 2 functions accepting integer array or string array.
But using Generic, we can make 1 method accepting generic type.



 func printAnyArray<T>(arr:[T]) {
       arr.map { print($0) }

 }


 <T> after the function name represents a generic function. A generic function can work with whatever type. We can put whatever instead of T. T is placeholder type. We can use for dictionary like Dictionary<key,value> and for array like Array<element> .

Generic function with parameter type : 


//Declare
func anotherMethod<T, U> (first: T, second: U) { print("first one called")}
func anotherMethod<T> (first: T, second: T) { print("second one called")}
//Call
anotherMethod(first: 123, second: "456"// T - Int, U - String
anotherMethod(first: 123, second: 456// T - Int




In above methods, we use different placeholder type in method1 and same placeholder type in method2. If out passing parameter types are different then 2nd method will be called, and if same then 1st method will be called.

Generic function with type constraints :


func middleVal<T>(array: [T]) -> T? {
  guard !array.isEmpty else { return nil }
  return array.sorted()[(array.count - 1) / 2]
}

   

Sometimes, we require specific types only i.e type which confirm comparable protocol


func middleVal<T: Comparable>(array: [T]) -> T? {
  guard !array.isEmpty else { return nil }
  return array.sorted()[(array.count - 1) / 2]
}

    

Above method will only accepts. int, float, double.


If you have any comment, question, or recommendation, feel free to post them in the comment section below!  

What is callback function?

Ans : A callback function is a function that is passed as an argument to another function, to be “called back” at a later time.

Code for Example :


func printValue(index: Int, element: Int) {
    print("index = \(index), Element = \(element)")
}
func each(array: [Int], callback: (Int, Int) -> Void) {
    for i in 0..<array.count {
        callback(i, array[i])
    }
}

each(array: [1, 2, 3, 4, 5],callback: printValue)


Here each function type is ( [Int], (Int, Int) -> Void ) .
Here callback function type is ( (Int, Int) -> Void ) .

Callback function mostly used when we want to pass block of code that should be executed in another function execution complete.

What are best approach to implement if large data is coming from core data and show data on tableview?

Ans : 

Use NSFetchResultsController : A controller that you use to manage the results of a Core Data fetch request and to display data to the user.


If we have very large data in database and we want all data to show in tableview, then we have to write some extra code on core data fetch request as fetching data will stuck UI.
Then we can use NSFetchResultsController as it has ability to fetch data from memory in batches. So data coming in batch when we scroll tableview and saved in cache.

We have to make property of type NSFetchResultsController :

- (NSFetchedResultsController *)fetchedResultsController {
    
    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
        entityForName:@"FailedBankInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    
    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
        initWithKey:@"details.closeDate" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    
    [fetchRequest setFetchBatchSize:20];
    
    NSFetchedResultsController *theFetchedResultsController =
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:managedObjectContext sectionNameKeyPath:nil
            cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    
    return _fetchedResultsController;
    
}


and in ViewDidLoad :

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSError *error;
 if (![[self fetchedResultsController] performFetch:&error]) {
  // Update to handle the error appropriately.
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  exit(-1);  // Fail
 }
    
    self.title = @"Failed Banks";
    
}


We get data in numberOfRowInSection :
id  sectionInfo =
        [[_fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];

We get data in cellForRowAtIndexPath :
FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];

We also have to write FetchResultsControllerDelegate methods as it is as at apple provide at end of ViewController's code.

Enjoy lazy loading data...

Tutorial : Ray Wanderlich


How you can add column in entity in core data that can be also added in next release?

Ans : When you initialise a Core Data stack, one of the steps involved is adding a store to the persistent store coordinator. When you encounter this step, Core Data does a few things prior to adding the store to the coordinator. First, Core Data analyzes the store’s model version. Next, it compares this version to the coordinator’s configured data model. If the store’s model version and the coordinator’s model version don’t match, Core Data will perform a migration, when enabled.

Note: If migrations aren’t enabled, and the store is incompatible with the model, Core Data will simply not attach the store to the coordinator and specify an error with an appropriate reason code.

Migrations happen in three steps:
  1. Core Data copies over all the objects from one data store to the next. 
  2. Core Data connects and relates all the objects according to the relationship mapping. 
  3. Enforce any data validations in the destination model. Core Data disables destination model validations during the data copy.
Database Migration : 

Lightweight Migration
Manual Migration
Custom Manual Migration
Fully Manual Migration

Setting for Lightweight Migration: 

NSMigratePersistentStoresAutomaticallyOption: true
NSInferMappingModelAutomaticallyOption: true


Coredata Migration Tutorial : RayWanderLich


What is Core Data Stacks?

Ans : Core Data is Apple’s object graph management and persistency framework.

Core Data Stack
Core Data Stack


  1. Managed Object
  2. Managed Object Context
  3. Managed Object Model
  4. Persistent Store Coordinator

  1. NSManagedObject’s are the model objects exposed by Core Data.
  2. NSManagedObjectModel is a database schema that describes the application’s entities. It defines the structure of the managed objects.
  3. NSPersistentStoreCoordinator associates persistent storage and managed object model. It lends itself to mapping the data from the storage, say SQLite data base rows, into the object model. It is a task of high complexity and is often taken for granted when working with Core Data.What is more, the persistent coordinator is used by the managed object context when it comes to saving or fetching objects.
  4. NSManagedObjectContext controls the life cycle of the managed objects and provides operations to create, save and fetch them. You can think of the managed object context as a scratch pad with a group of managed objects.

Starting from iOS 10, NSPersistentContainer is responsible for creation and management of the Core Data stack.
NSPersistentContainer exposes a managed object model, a managed object context and a persistent store coordinator as well as provides many convenience methods when working them, especially when it comes to multithreaded applications.



What is delete rule in Core Data?

Ans : In our database, there may be multiple entities. One entity is connected with another entity in relationship. So deleting one data from one entity may have impact on another entity data depends on relationship or delete rule.

There are 4 delete rules :

  1. No Action
  2. Nullify
  3. Cascade
  4. Deny
Let's take example having one department entity and it is connected to employee entity with relationship as one-to-many. Employee to department entity relationship is one-to-one.

1. No Action : When No Action delete rule is set to relationship, then there will be no impact of deleting record from one entity. If we delete record from department connected to multiple employees, then there be no impact on employee entity. Employee assume that it has still relation with deleted department.

2. Nullify : If delete rule is set to Nullify to the relationship then the destination of the relationship gets nullify.  In our case, if department is deleted, then relationship between employee and department gets nullify. This is default delete rule.

3. Cascade Rule : If we delete department, then its related employees will be deleted if this delete rule is set. This rue is only used when data model has more dependency. 

4. Deny Delete Rule : This is opposite of Cascade Rule. If we set this rule, and we try to delete department which is connected to any of employee, then we are not allowed to delete department.

Depends on project requirement, we can set delete rule.


What is lazy loading?

Ans :  Lazy Loading Images is a technique to resolve loading image from the web. The thing is that, I need to display images directly from the web in UIImageView or any other control. 

For this, if you simply try to set the image using in-built setImage method then your application gets stuck while loading image from the web. To overcome this issue, there is a technique generally known as Lazy Loading Image. The thing actually happening in lazy loading is that the task of image loading from web is performed in background and at that time a temporary placeholder image is displayed in the control. When the actual image is fully loaded from the web, it is replaced with the placeholder image and you get your actual image on the control without having stuck interface.

You can use third party library to load image :  SDWebImage

Try to make own coding for loading image from URL and Save in cache and display in imageView.



What is apple enterprise account?

Ans : 

To Develop and Distribute app, there are two types of licence available.

1. Apple Developer
2. Apple Developer Enterprise

Difference : 



Source : LeoLearning



Can I store null value in info.plist?

Ans : 

Null or NSNull value type is not supported in info.plist file. Base type of info.plist file is array or dictionary. In array or dictionary, you can save only following type :


  1. Array
  2. Dictionary
  3. Boolean
  4. Data
  5. Date
  6. Number
  7. String
No above type supports nil value. They are not optional. So null or nil value can not be stored in info.plist file.

What is .dSYM file?

Ans :

A dSYM file is "debug symbol file". It is generated when "strip debug symbols" setting is enabled in build setting.

When this setting is enabled, symbol names of your objects are removed from the resulting compiled binary  (Benefit of this is protect our code from hackers/crackers to reverse engineering your code, amongst other optimisations for binary size, etc.).

dSYM files will likely change each time your app is compiled.

They are useful for re-symbolicating your crash reports. With a stripped binary, you won't be able to read any crash reports without first re-symbolicating them. Without the dSYM the crash report will just show memory addresses of objects and methods. Xcode uses the dSYM to put the symbols back into the crash report and allow you to read it properly.

 The created archive contains your app and its dSYM and is stored within Xcode's derived data directory. It is good if we keep dSYM file in every where like build fro QA, UAT, Appstore, Distribution.

For debug mode, if "strip debug symbols"  setting is set to "No" then it is okay, but for release, "Yes" is recommended for read crash report.


If you have any comment, question, or recommendation, feel free to post them in the comment section below!  

Json serialization and deserialization

Ans :  


JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
When transmitting data or storing them in a file, the data are required to be byte strings, but complex objects are seldom in this format. Serialization can convert these complex objects into byte strings for such use. After the byte strings are transmitted, the receiver will have to recover the original object from the byte string. This is known as deserialization.

import UIKit

var str = "Hello, playground"

// Starting decode -> json to class or object
// ------------- De-Serialization ----------------

let singleDict = """
{
    "foodName" : "Banana"
    "calories" : 100
}
""".data(using: .utf8)

class Food : Codable {
    
    let foodname : String
    let calories : Int
    
    init(foodname: String, calories: Int) {
        self.foodname = foodname
        self.calories = calories
    }
}

let jsonDecoder = JSONDecoder()
do {
    let foodResult = try jsonDecoder.decode(Food.self, from: singleDict!)
    print(foodResult.foodname)
} catch {
    print("failed to decode \(error.localizedDescription)")
}

// Starting encode -> class or object to json
// ------------- Serialization ----------------

let apple = Food(foodname: "apple", calories: 80)
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
do {
    let jsonData = try jsonEncoder.encode(apple)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
} catch {
    

}

If you have any comment, question, or recommendation, feel free to post them in the comment section below!

What is Deep link in iOS?

Ans : 

Deep linking is the idea of not only having a clickable link to open up your app but a smart one that will also navigate to the desired resource.

There are 2 ways of implementing deep linking in IOS: URL scheme and Universal Links.

Comparison :


 Neither of these options will redirect you to the App Store if the app is not installed.

URL Scheme : 

Open Xcode, got to Project Settings -> Info, and add inside ‘The URL Types” section a new URL scheme. Add something of the sort of com.myApp and that’s it. Now install your app, open the app notes and type com.myApp and press enter.



Nothing will happen as IOS do not recognise this as URL. So, type com.myApp://main. Now when we press enter, we can see IOS detected the link and when we click it, a pop up will ask for permission to open MyApp from Notes.

To redirect to specific page or controller : 

Write following AppDelegate method,

  func application(_ app: UIApplication, open url: URL,
                     options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        if let scheme = url.scheme,
            scheme.localizedCaseInsensitiveCompare("com.myApp") == .orderedSame,
            let view = url.host {
            
            var parameters: [String: String] = [:]
            URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
                parameters[$0.name] = $0.value
            }
            
            redirect(to: view, with: parameters)
        }
        return true
    }


and open com.myApp://profile?user=”mananshah”  from notes app.
Here,
     url.scheme = “com.myApp”
     url.host = “profile”
     parameters = [ “user” : “mananshah” ]

This URL will not work if app is not installed. If app is not installed, this will open safari and show blank page. For solving, we should implement Universal link.

Universal Link : 

Universal links are a bit more complex. Basically, we want IOS to relate a webpage URL to our app. Hitting URL expect a json in following format to ensure valid apps :

{
        “applinks”: {
            “apps”: [],
            “details”: [
                {
                    “appID”: “T5TQ36Q2SQ.com.myapp.production”,
                    “paths”: [“*”],
                }
            ]
        }

    }

Applinks indicate this is indeed for the Universal Link declaration.
Apps should be left as an empty array. This is most likely because these types of JSON are used for other purposes other than universal links as well.
Details will then contain an array of your apps and the mapping of each subpath to the respective app.
For each app, you should add a field called appID which is obtained concatenating your teamID and your app’s bundleID. For example, if your TeamID is 123456 and your AppID is com.myApp, then the result is 123456.com.myApp.
In the paths field, an array of strings representing with expressions of the paths which correspond to this app. For example, if you want myApp.com/store to open up a different app than myApp.com/maps, here you can declare that is a wildcard for any string, while ? is a wildcard for any character. As we only have one app, any subpath will lead here, hence the *. If you want to exclude a subpath, just add NOT at the beginning.
-----
Once that is done, we now must add the correct metadata to the app. 
First, open Xcode, go to Project settings -> capabilities. Scroll down to Associated Domains and turn it on. Once it is enabled, we shall add any URL that implements our apple-app-site-association resource, preceded by app links. Inside the Domains section, add a applinks:myApp.com. Once this is done, go ahead and try out your app.
To redirect to specific page or controller : 


public func application(_ application: UIApplication,
                               continue userActivity: NSUserActivity,
                               restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
           if let url = userActivity.webpageURL {
               var view = url.lastPathComponent
               var parameters: [String: String] = [:]
               URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.forEach {
                   parameters[$0.name] = $0.value
               }
               
               redirect(to: view, with: parameters)
           }
           return true
      }



Universal links allow us to have a fallback webpage if a user does not have the app installed
if the user has the app, the link will open it, and if not, it will fall under the webpage.

Credit : WOLOX