Wednesday, 6 January 2021

iOS Interview Questions

iOS Interview Questions


Enum is a type that basically contains a group of related values

—>  (iOS Application Lifecycle)
  • Not Running: This is a simple state in which our app is not launched or no code is being executed and terminated by the system and the application is completely switched off.
  • Inactive: This state is just a transitional state. Inactive state means our application is running in the background but is not able to receive events.
  • Active: Active state is the main execution state, where our app is running in the background and is able to receive events.
  • Background: This is the state where our App is running in the background and still is able to execute the code in the background.
  • Suspended: This state means that our app running is in the background state and the system suspends this app and the application cannot execute any code.
    SceneDelegate
        1 scene(_:willConnectTo:options:) This method will creates new UIWindow, sets the root view controller and makes this window the key window to be displayed
    2. sceneDidDisconnect(_:)
the scene is sent to background
    3. sceneDidBecomeActive(_:)
    4. sceneWillResignActive(_:)
    5. sceneWillEnterForeground(_:)
    6. sceneDidEnterBackground(_:)

—>JSON framework is supported by iOS?
Answer: SBJson

—> Protocol 
The protocol is a concept that is similar to an interface from java


—> What is the Swift main advantage ?
To mention some of the main advantages of Swift:
1 Optional Types, which make applications crash-resistant
2 Built-in error handling
3 Closures
4 Much faster compared to other languages
5 Type-safe language



—>DispatchQueue:
There are two types of DispatchQueue-
  • Serial Queue (a work item starts to be executed once the previous one has finished execution)👍
  • Concurrent Queue (work items are executed concurrently  not necessarily simultaneously)
Threading>>
concurrency where multiple tasks can be executed at the same time but not necessarily simultaneously. 
Example:(wait another task) we playing game and what’s app notification read, then reply and again play game

parallelism means when the computer is doing two or more tasks simultaneously without any waiting
synchronous programming, your program is executed line by line, one line at a time
Asynchronous programming is a form of parallel programming that allows a unit of work to run separately from the primary application thread


—>GCD
>>>
Grand Central Dispatch is used in iOS to introduce concurrency and parallelism in the iOS applications, so that multiple heavy tasks are performed in the background, resulting in the smooth experience of the application usage, as the main thread is unaffected by the heavy background tasks.


Apple provides two ways to do multitasking: The Grand Central Dispatch(GCD) and NSOperationQueue frameworks.
NSOperationNSOperationQueueNSBlockOperation

GCD advantage over NSOperation:
i. implementation
For GCD implementation is very light-weight
NSOperationQueue is complex and heavy-weight
NSOperation advantages over GCD:
i. Control On Operation
you can Pause, Cancel, Resume an NSOperation
ii. Dependencies
you can set up a dependency between two NSOperations
operation will not started until all of its dependencies return true for finished.
iii. State of Operation
can monitor the state of an operation or operation queue. ready ,executing or finished
iv. Max Number of Operation
you can specify the maximum number of queued operations that can run simultaneously


—>Safe delete method in code data
>>>

—>Codable decodable
>>>

Encoding
The process of converting your custom type instances to other representation such as JSON and pList is known as Encoding or Serialization. For encoding, custom types conform to Encodable protocol.
Decoding
The process of converting data in representation such as JSON or pList to instance of your custom type is known as Decoding or Deserialization. For decoding, custom types conform to Decodable protocol.
Codable
To support both encoding and decoding, custom types can conform to Codable protocol which conforms to both Encodable and Decodable.




—>Type Safety
Swift is a type-safe language. A type safe language encourages you to be clear about the types of values your code can work with. If part of your code expects a String, you can’t pass it an Int by mistake.
var welcomeMessage: String  //Type Annotation
welcomeMessage = 22 // this would create an error because you  
//already specified that it's going to be a String

—>Type Inference
If you don’t specify the type of value you need(var name = false), Swift uses type inference to work out the appropriate type. Type inference enables a compiler to deduce the type of a particular expression automatically when it compiles your code, simply by examining the values you provide.
var meaningOfLife = 42 // meaningOfLife is inferred to be of type Int
meaningOfLife = 55 // it Works, because 55 is an Int

—>What do you mean by the term “defer”?
defer statement execution until the current scope is exited. This statement consists of the deferkeyword and the statements to be executed later, LIFO
defer { print(“4”)}
defer { print(“5”)}
defer { print(“6”)}

it will print :
6
5
4

—>What is an attribute in Swift?
Attributes can be specified with @ symbol followed by attribute name and arguments. Arguments are specific only to certain attributes 
Ex : @available(<attribute_name>)
@available(iOS 9, macOS 10.10, *) 

available is a declaration attribute which can be used to specify the Swift language version, platform or iOS version 

unavailable This can be used to specify if code is unavailable on certain platform or not

Obsolete is used to make code unavailable

deprecated is just to raise warning that code is deprecated

introduced This argument specifies the language or version in which the routine was introduced. You cannot use the routine before introduced version number.
// Only available in targets pointing to iOS versions greater than 10.1
@available(iOS, introduced: 10.1)

@testable
This attribute is used when you want to import certain modules in your test class for unit testing
@objc
This attribute is used when constructs (classes, non-generic enums, protocols) in Swift are needed to be made available in Objective-C code




—> What is the bounding box
we usually use a bounding box to describe the target location(focus on object like camera focus). The bounding box is a rectangular box that can be determined by the
𝑥x and 𝑦y axis coordinates in the upper-left corner and the 𝑥x and 𝑦y axis coordinates in the lower-right corner of the rectangle [Camera Focus on map]

—> What is @synthesize in Objective-C
@synthesize creates a getter and a setter for the variable., Access Variable Without self and leading underscore.

—>What is typealias
declaration introduces a named alias of an existing type into your program
Ex: typealias MapView = Double // Map view a name alias for double data type 

—>What is @dynamic in Objective-C
Using dynamic tells Swift to always refer to Objective-C dynamic dispatch,


—>What is Dynamic Dispatch
dynamic dispatch happen at runtime with the help of a virtual table.(For which operation perfome)
dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.

—>What’s Code Coverage
 Its under the unit testing for How many line of code executed compile time

—>What is Responder Chain 
If the view is the root view of a view controller, the next responder is the view controller.
It works from view—> ViewController—> UiWindow—> Application


—>What is function overloading?
The process we just described is known as function overloading. By definition, the process of creating two or more than two functions with the same name but having different number or types of parameters passed is known as function overloading



—> How many are there APIs for battery-efficient location tracking
There are 3 APIs for battery-efficient location tracking:
Significant location changes — the location is delivered approximately every 500 metres (usually up to 1 km)
Region monitoring — track enter/exit events from circular regions with a radius equal to 100m or more.
Visit events — monitor place Visit events which are enters/exits from a place (home/office).



—> Frame and Bounds
frame = a view’s location and size using the parent view’s coordinate system (important for placing the view in the parent) [x=40,y=50,w=200,h=300 current location from superview]
bounds = a view’s location and size using its own coordinate system (important for placing the view’s content or subviews within itself) [x=0,y=0,w=200,h=300 current coordinates]

What is Operator Overloading

What is JSON/PLIST limits 
  • It’s great and very limited use cases.
  • We can’t obviously use complex queries to filter your results.
  • It’s very slow.
  • Each time we need something, we need to either serialize or deserialize it.
  • it’s not thread-safe.

-

—> Diff IB Designable IB ISpactable
IBInspectable and IBDesignable are used to render elements directly in Interface Builder
IBDesignable attribute is responsible to identifier the class inherits from the UIView that will render in Interface Builder.
IBInspectable is another attribute that can be used to configure your UI component

Diff Unowned weak
Use a weak reference whenever it is valid for that reference to become nil at some point during its lifetime.
 Conversely, use an unowned reference when you know that the reference will never be nil once it has been set during initialization

Error
NSError(domain:"", code:httpResponse.statusCode, userInfo:nil)

Diff Class and structure
Class is reference type, Struct is value type
Classes and structs have initializers to create instances with initial values
Finally, they can be extended.
Classes have an inheritance, whereas structs cannot have an inheritance

—> Diff Function and closures
Function:
You define a function with the func keyword. Functions can take many parameters and return none, one or multiple parameters (using tuples, we can return multiple values at a time

Closures are just un-named or anonymous functions

Diff Protocol and closures
Diff Escaping  nonEscaping
Diff Map and flat map difference

—> ABI stability

        >>> Now Swift 5 is ABI Stable, Swift will be embeded within the iOS Operating System and it’s ABI will be         compatible with every version of Swift. i.e Apple Music is using Swift 5.0, but Notes app is using Swift 5.2, and both are consuming Swift ABI embedded in the Operating System.


This means that if any changes occur in future Swift versions it will come with the OS on which developer is working on and gets automatically used by the app when it is running on that OS without the need to recompile and redeliver app.



—> Dependency Injection


     It is injecting dependencies into an object instead of tasking the object


    (https://cocoacasts.com/dependency-injection-in-swift)


example,

     we define a UIViewController subclass that declares a property, requestManager, of type rquestManager?.

      import UIKit

     class ViewController: UIViewController {


        var requestManager: RequestManager?


     }


Note:- We can set the value of the requestManager property one of two ways.


Without Dependency Injection

The first option is to task the ViewController class with the instantiation of the RequestManager instance. We can make the property lazy or initialize the request manager in the view controller's initializer. That's not the point, though. The point is that the view controller is in charge of creating the RequestManager instance.

import UIKit


class ViewController: UIViewController {


    lazy var requestManager: RequestManager? = RequestManager()


}

This means that the ViewController class not only knows about the behavior of the RequestManager class. It also knows about its instantiation. That's a subtle but important detail.


With Dependency Injection

But there's another option. We can inject the RequestManager instance into the ViewController instance. Even though the end result may appear identical, it definitely isn't. By injecting the request manager, the view controller doesn't know how to instantiate the request manager.

// Initialize View Controller

let viewController = ViewController()


// Configure View Controller

viewController.requestManager = RequestManager()

Many developers immediately discard this option because it's cumbersome and unnecessarily complex. But if you consider the benefits, dependency injection becomes more appealing.


Types

Most developers consider three forms or types of dependency injection:

  • initializer injection
  • property injection
  • method injection

These types shouldn't be considered equal, though. Let me list the pros and cons of each type.

Initializer Injection

I personally prefer to pass dependencies during the initialization phase of an object because this has several key benefits. The most important benefit is that dependencies passed in during initialization can be made immutable. This is very easy to do in Swift by declaring the properties for the dependencies as constants. Take a look at this example.


class DataManager {


    private let serializer: Serializer


    init(serializer: Serializer) {

        self.serializer = serializer

    }


}



let serializer = RequestSerializer()


let dataManager = DataManager(serializer: serializer)


The only way to set the serializer property is by passing it as an argument during initialization. The init(serializer:) method is the designated initializer and guarantees that the DataManager instance is correctly configured. Another benefit is that the serializer property cannot be mutated.

Because we are required to pass the serializer as an argument during initialization, the designated initializer clearly shows what the dependencies of the DataManager class are.


Property Injection

Dependencies can also be injected by declaring an internal or public property on the class or structure that requires the dependency. This may seem convenient, but it adds a loophole in that the dependency can be modified or replaced. In other words, the dependency isn't immutable.

import UIKit


class ViewController: UIViewController {


    var requestManager: RequestManager?


}


let viewController = ViewController()


viewController.requestManager = RequestManager()


Property injection is sometimes the only option you have. If you use storyboards, for example, you cannot implement a custom initializer and use initializer injection. Property injection is then your next best option.


Method Injection

Dependencies can also be injected whenever they are needed. This is easy to do by defining a method that accepts the dependency as a parameter. In this example, the serializer isn't a property on the DataManager class. Instead, the serializer is injected as an argument of the serializeRequest(_:with:) method.

class DataManager {


    func serializeRequest(request: Request, with serializer: Serializer) -> NSData? {

        ...

    }


}


Even though the DataManager class loses some control over the dependency, the serializer, this type of dependency injection introduces flexibility. Depending on the use case, we can choose what type of serializer to pass into serializeRequest(_:with:).

It's important to emphasize that each type of dependency injection has its use cases. While initializer injection is a great option in many scenarios, that doesn't make it best or preferred type. Consider the use case and then decide which type of dependency injection is the best fit.



//////////////////////////////////////////////////////////////



—> Singleton

Singletons are easy to understand. The singleton pattern guarantees that only one instance of a class is instantiated





class NetworkManager {

    static let shared = NetworkManager()

    // Static type property, which is guaranteed to be lazily initialized only once

}


NetworkManager.shared




/////////////////////////////////////////////////////////////



—> Generic 

(https://learnappmaking.com/generics-swift-how-to/)


With generics you can write clear, flexible and reusable code. You avoid writing the same code twice,and avoid duplication, and it lets you write generic code in an expressive manner. its abstracted manner



Let’s take the original addition(a:b:) function, and turn it into a generic function. Like this:


func addition<T: Numeric>(a: T, b: T) -> T

{

    return a + b

}


let a = addition(a: 42, b: 99)

print(a)

// Output: 141


let b = addition(a: 0.99, b: 0.33)

print(b)

// Output: 1.32


let c = addition(a: Double.pi, b: Double.pi)



/////////////////////////////////////////////////////////////



—> Access control/Access Specifier 

(https://singhdivesh.medium.com/ios-and-macos-developer-traveler-9b9640476dc2)


==>  Open and public comes to picture when we are talking about different target/module.


==>  Internal, FilePrivate and private is used within Target/module


Open : This Access level is everywhere, can access within function, within class, within file, outside of target and even can override as well

Public : Same as open but can not override.

Internal : This is default access level. It can be access within module everywhere.

FilePrivate — This access level area is within file if multiple classes exits in the same file, that also can be accessible

private — access within body where you have written privat






/////////////////////////////////////////////////////////////


—> Higher-order function

 (https://levelup.gitconnected.com/higher-order-functions-in-swift-35861620ad1)


A higher-order function is a function that takes one or more functions as arguments or returns a function as its result. It will speed up your software development skills.


swift higher-order functions — forEach, map, CompactMap, flatMap, filter, reduce, sort, and sorted.


let coins = [1, 5, 2, 10, 6]


ForEach

forEach will iterate through all elements in an array and will not return anything.

simple


for coin in coins {

print("\(coin)$", terminator: " ")

}

For Each

coins.forEach { print("\($0)$", terminator: " ") }


“forEach” works like “for in” but the basic difference is, you can’t use break and continue statement to exit from the closure for forEach.



Map

map will iterate through all elements in an array and will return an updated array.

let coins = [1, 5, 2, 10, 6]


simple


var coinsWithCurrency: [String] = []

for coin in coins {

coinsWithCurrency.append("\(coin)$")

}

print(coinsWithCurrency)


        

let coinsWithCurrencyUsingMap_shortSyntax = coins.map { "\($0)$" }


compactMap

compactMap will iterate through all elements in an array and will return an updated array only with the elements which satisfied the condition written inside the body of compactMap. Any element which resulting in a nil value will be excluded from the updated array.



let coins = ["1", "5", "$", "10", "6"]


simple


var validCoins: [Int] = []

for coin in coins {

if let coin = Int(coin) {

validCoins.append(coin)

}

}

print(validCoins)


let validCoinsUsingCompactMap_shortSyntax = coins.compactMap { Int($0) }



flatMap

flatMap converts 2D array to one dimensional array.


let arrayOfCoins = [[1, 5, 2, 10, 6],[2, 7, 4, 10, 15]]


let arrayOfCoin = arrayOfCoins.flatMap { (coins) in

coins

}

print(arrayOfCoin)

let arrayOfCoin_ShortSyntax = arrayOfCoins.flatMap { $0 }

print(arrayOfCoin_ShortSyntax)




filter

filter will iterate through all elements in an array and will return an updated array only with the elements which satisfied the condition written inside the body of filter.



let coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]


let coinsWithValueLessThanSix = coins.filter { (coin) -> Bool in

coin < 6

}

print(coinsWithValueLessThanSix)



let coinsWithValueLessThanSixShortSyntax = coins.filter { $0 < 6 }

print(coinsWithValueLessThanSixShortSyntax)


reduce


reduce will iterate through all elements in an array and returns an object with a combined value of all elements.

syntax -

reduce(initialResult, (currentResult, currentElement) -> Return finalResult)


let coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]


let sumOfCoins = coins.reduce(0) { (result, coin) -> Int in

result + coin

}

let sumOfCoinsShortSyntax = coins.reduce(0, { $0 + $1 })


outpost string “1521062741015”



sort(by:) and sorted(by:)

sort(by:) will sort all elements according to the condition written inside the body of the closure.

sorted(by:) will sort all elements according to the condition written inside the body of the closure and returns a new array.


var coins = [1, 5, 2, 10, 6, 2, 7, 4, 10, 15]

let sortCoins = coins.sorted { (a, b) -> Bool in

a > b

}


coins.sort { (a, b) -> Bool in

a > b

}

print(sortCoins)

print(coins)


->Beta Testing 

It is invite users to test your apps and app clip experiences and collect valuable feedback before releasing your apps on the App Store.


Internal Tester

Add up to 100 members of your team who have been assigned the Account Holder, Admin, App Manager, Developer, or Marketing role to quickly test beta builds as you iterate on your app. Each member can test on up to 30 devices. Internal testers can access all of your beta builds available for testing


External tester

Invite up to 10,000 external testers using their email address or by enabling and sharing a public link, which creates an open invitation for anyone to test your app





->App Store Regarding

App name ,subtitle text limit = 30 character

What's New in This Version and Description text limit = 4000 characters

Promotional text limit = 170  characters


App size limit  4GB uncompressed

App clip Size  10 mb

Photo size

6.5” => 1242*2688  ==> XS_max , 11_pro_max

5.5” => 1242*2208  ==> 6+,6s+,7+,8+


Kewords = 100



-> NotificationCenterDelegate


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

 func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)

 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)