Search Your Question

What is QOS?

Ans : 

QOS - Quality of Services

A quality-of-service (QoS) class categorizes work to be performed on a DispatchQueue. By specifying the quality of a task, you indicate its importance to your app. When scheduling tasks, the system prioritizes those that have higher service classes.

Because higher priority work is performed more quickly and with more resources than lower priority work, it typically requires more energy than lower priority work. Accurately specifying appropriate QoS classes for the work your app performs ensures that your app is responsive and energy efficient.

Levels of Priority
After an app kicks off and starts a runloop on the main thread, one can begin taking advantage of QoS. QoS breaks out priorities into four different groups. Each one corresponds to common tasks one might find themselves coding in their iOS endeavors.
  • User Interactive: Work that happens on the main thread, such as animations or drawing operations.
  • User Initiated: Work that the user kicks off and should yield immediate results. This work must be completed for the user to continue.
  • Utility: Work that may take a bit and doesn’t need to finish right away. Analogous to progress bars and importing data.
  • Background: This work isn’t visible to the user. Backups, syncs, indexing, etc.


There are five global queues having quality of service level ranging  from high performance to high energy efficiency. 
  1. DispatchQueue.global(qos: .userInteractive) - highest priority
  2. DispatchQueue.global(qos: .userInitiated)
  3. DispatchQueue.global() // default
  4. DispatchQueue.global(qos: .utility)
  5. DispatchQueue.global(qos: .background) - lowest priority 
DispatchQueue.global(qos: .userInteractive).async {
 // Event handling task
}


What is mutating in swift?

Ans :

If you have ever tried using the mutating keyword in your class methods in Swift, the compiler will definitely yell at you because you are doing something wrong.
In swift, classes are reference type whereas structures and enumerations are value typesThe properties of value types cannot be modified within its instance methods by default. In order to modify the properties of a value type, you have to use the mutating keyword in the instance method. With this keyword, your method can then have the ability to mutate the values of the properties and write it back to the original structure when the method implementation ends.
Below is a simple implementation of Stack in Swift that illustrates the use of mutating functions.

struct Stack {
     var items = [Int]() // Empty items array
    
    mutating func push(_ item: Int) {
        items.append(item)
    }
    
    mutating func pop() -> Int? {
        if !items.isEmpty {
           return items.removeLast()
        }
        return nil
    }
}

var stack = Stack()
stack.push(4)
stack.push(78)
stack.items // [4, 78]
stack.pop()

stack.items // [4]

You can change the value of items by creating an instance of Stack. But without mutating keyword function can not change property.

Classes are reference type whereas Structures and Enumerations are of a value type in swift. What does that mean is that a class object shares a single instance of the object and passes the same reference if passed to any function or new object whereas the value type is the one which creates a copy of it and passes only the value.
If we try to change any variable inside a class it’s straightforward.

What is delegation pattern?

Ans : 

A design pattern is a generalized way of arranging different parts of code. The main motive behind using a design pattern is to achieve better readability and code reusability.

Delegation is a design pattern that makes a component in code delegate its task(s) to a different component.

In order to make communication possible in two ways, we should use delegate. We can achieve this using delegate-protocol in Objective-C and Swift.

We should use delegate as Weak due to avoid memory leaks.

Read :  Usage of Delegate-Protocol


Write a program for sorting array. Quick sort, merge sort, Heap Sort

Ans : 

Quick Sorting Integer Array - Explanation


func swap<T: Comparable>(leftValue: inout T, rightValue: inout T) {
    (leftValue, rightValue) = (rightValue, leftValue)
}

func partition<T: Comparable>(array: inout [T], startIndex: Int, endIndex: Int) -> Int {
    var q = startIndex
    for index in startIndex..<endIndex {
        if array[index] < array[endIndex] {
            swap(leftValue: &array[q], rightValue: &array[index])
            q += 1
        }
    }
    swap(leftValue: &array[q], rightValue: &array[endIndex])
    return q
}
func quickSort<T: Comparable>(array: inout [T], startIndex: Int, endIndex: Int) {
    // Base case
    if startIndex >= endIndex {
        return
    }
    let placedItemIndex = partition(array: &array, startIndex: startIndex, endIndex: endIndex)
    quickSort(array: &array, startIndex: startIndex, endIndex: placedItemIndex-1)
    quickSort(array: &array, startIndex: placedItemIndex+1, endIndex: endIndex)
}
func quickSort<T: Comparable>(array: inout [T]) {
    quickSort(array: &array, startIndex: 0, endIndex: array.count-1)
}
var numbers = [13, 77, 20, 45, 2, 15, 0, 59, 5, 68, 51, 1, -1, 77]

quickSort(array: &numbers)


Merge Sorting Integer Array - Explanation


func merge<T: Comparable> (array: inout [T], startIndex: Int, middleIndex: Int, endIndex: Int) {
    let leftSubarray = Array(array[startIndex...middleIndex])
    let rightSubarray = Array(array[middleIndex+1...endIndex])
    var index = startIndex
    var leftIndex = 0
    var rightIndex = 0
    while leftIndex < leftSubarray.count && rightIndex < rightSubarray.count {
        if leftSubarray[leftIndex] < rightSubarray[rightIndex] {
            array[index] = leftSubarray[leftIndex]
            leftIndex += 1
        }
        else {
            array[index] = rightSubarray[rightIndex]
            rightIndex += 1
        }
        index += 1
    }
    while leftIndex < leftSubarray.count {
        array[index] = leftSubarray[leftIndex]
        index += 1
        leftIndex += 1
    }
    while rightIndex < rightSubarray.count {
        array[index] = rightSubarray[rightIndex]
        index += 1
        rightIndex += 1
    }
}

func mergeSort<T: Comparable>(array: inout [T], startIndex: Int, endIndex: Int) {
    // Base case
    if startIndex >= endIndex {
        return
    }
    let middleIndex = (startIndex + endIndex) / 2
    mergeSort(array: &array, startIndex: startIndex, endIndex: middleIndex)
    mergeSort(array: &array, startIndex: middleIndex+1, endIndex: endIndex)
    merge(array: &array, startIndex: startIndex, middleIndex: middleIndex, endIndex: endIndex)
}
func mergeSort<T: Comparable>(array: inout [T]) {
    mergeSort(array: &array, startIndex: 0, endIndex: array.count-1)
}

var numbers = [13, 77, 20, 45, 2, 15, 0, 59, 5, 68, 51, 1, -1, 77]
mergeSort(array: &numbers)





Heap Sorting Integer Array - Explanation

extension Heap {
    public mutating func sort() -> [T] {
        for i in stride(from: (nodes.count - 1), through: 1, by: -1) {
            nodes.swapAt(0, i)
            shiftDown(from: 0, until: i)
        }
        return nodes
    }
}
/*
 Sorts an array using a heap.
 Heapsort can be performed in-place, but it is not a stable sort.
 */
public func heapsort<T>(_ a: [T], _ sort: @escaping (T, T) -> Bool) -> [T] {
    let reverseOrder = { i1, i2 in sort(i2, i1) }
    var h = Heap(array: a, sort: reverseOrder)
    return h.sort()
}

//Testing
func testSort() {
    var h1 = Heap(array: [5, 13, 2, 25, 7, 17, 20, 8, 4], sort: >)
    let a1 = h1.sort()
}

// output : [2, 4, 5, 7, 8, 13, 17, 20, 25]


Difference between category in Objective C and extension Swift?

Ans : 

Differences between Objective-C Category and Extension


1. Factor : Source code
Categories provide a way to add methods to a class even if its source code is not available to you. ex: NSString
Extensions are only possible if the source code is available , because compiler compiles the extension & source code at same time.
2. Factor : Instance variable/Properties
Category : Not possible
Extensions : Possible
3. Factor : Accessibility to Inherited classes.
Category — All methods defined inside a category are also available to the inherited class
Extensions — All properties and methods defined inside a class extension are not even available to inherited class.
When to use : 
Use category when you need to want to add any methods to a class whose source code is not available to you OR you want to break down a class into several files depending on its functionality.
Use class extensions when you want to add some required methods to your class outside the main interface file. Also when you want to modify a publicly declared variable in the main interface file .


Difference between Objective-C category and Swift extension :

Mostly Objective-C category and Swift extension are same. 

Diff : 

In Objective-C category, Computed property/variable can not be declared.
In Swift extension, Computed property(not stored property) can be declared.


Difference between pod install and pod update

Ans : 

pod install

This is to be used the first time you want to retrieve the pods for the project, but also every time you edit your Podfile to add, update or remove a pod.

Every time the pod install command is run — and downloads and install new pods — it writes the version it has installed, for each pods, in the Podfile.lock file. This file keeps track of the installed version of each pod and locks those versions.
When you run pod install, it only resolves dependencies for pods that are not already listed in the Podfile.lock.
For pods listed in the Podfile.lock, it downloads the explicit version listed in the Podfile.lock without trying to check if a newer version is available
For pods not listed in the Podfile.lock yet, it searches for the version that matches what is described in the Podfile (like in pod 'MyPod', '~>1.2')

pod outdated

When you run pod outdated, CocoaPods will list all pods which have newer versions than the ones listed in the Podfile.lock (the versions currently installed for each pod). This means that if you run pod update PODNAME on those pods, they will be updated — as long as the new version still matches the restrictions like pod 'MyPod', '~>x.y' set in your Podfile.

pod update

When you run pod update PODNAME, CocoaPods will try to find an updated version of the pod PODNAME, without taking into account the version listed in Podfile.lock. It will update the pod to the latest version possible (as long as it matches the version restrictions in your Podfile).

If you run pod update with no pod name, CocoaPods will update every pod listed in your Podfile to the latest version possible.


How to cancel alamofire api request?

Ans:

You can cancel a single request as below:
1 - First get the request:
let request = Alamofire.SessionManager.default.request(path!, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: createHeader()).responseJSON { response in
    switch response.result {
    case .success(let data):
        success(data as AnyObject?)
    case .failure(let error) :
        failure(error as NSError)
    }
}
2 - Then, in your viewDidDisappear, just call:
request.cancel()

You can cancel all requests as below:
Alamofire.SessionManager.default.session.getTasksWithCompletionHandler { (sessionDataTask, uploadData, downloadData) in
    sessionDataTask.forEach { $0.cancel() }
    uploadData.forEach { $0.cancel() }
    downloadData.forEach { $0.cancel() }
}

According to different alamofire and swift version, above code may change little bit.