Search Your Question

Showing posts with label Reliance Mutual Fund. Show all posts
Showing posts with label Reliance Mutual Fund. Show all posts

Difference between OperationQueue and DispatchGroup

Ans : 

You probably found yourself in a situation where you had to do a bunch of asynchronous tasks and you just wanted to get notified when all of them finish. There are two easy ways of doing this: DispatchGroup and OperationQueue. 

DispatchGroup :

DispatchGroups is probably the easiest way for you to know when a bunch of asynchronous calls is finished.  DispatchGroup is a part of GCD and in Swift 3 we got a nice swiftified GCD.

func getMovies(onCompleted: (([MovieItem]) -> ())?) {
    
    var result: [MovieItem] = []
    
    let dispatchGroup = DispatchGroup()
    
    for i in 1...5 {
        guard
            let urlString = DataSourceConstants.URLString(forPage: "\(i)")
            else {
                continue
        }
        
        dispatchGroup.enter()
        self.networkingProvider.restCall(urlString: urlString) {
            
            (responseObject) in
            
            guard
                let responseData = responseObject,
                let jsonObject = try? JSONSerialization.jsonObject(with: responseData, options: [JSONSerialization.ReadingOptions.allowFragments])
                else {
                    dispatchGroup.leave()
                    return
            }
            
            let movies = self.moviesFactory.movieItems(withJSON: jsonObject)
            result = result + movies
            
            dispatchGroup.leave()
        }
    }
    
    dispatchGroup.notify(queue: DispatchQueue.global()) {
        onCompleted?(result)
    }

}

Here we create your DispatchGroup at the top of the function and just before you execute an async piece of code, you enter the group. In your closure, you leave the same group just before the closure completes. When your DispatchGroup is empty, a closure will be called.

What’s really important here is the enter-leave pairs. You have to be very careful and make sure that you leave the group. It would be easy to introduce a bug in the code above. Let’s say that we didn’t leave the group in that guard statement above, just before the return. If the API called failed, or the JSON was malformed, the number of group entries would not match the number of leaves. So the group completion handler would never get called. If you’re calling this method from the UI and displaying an activity indicator while your networking requests are running, you would never get a callback from the method, and you would keep on spinning.

OperationQueue :

Operation queues are great and all, but if you just want to know when your queue is finished you won’t find a ready-made API waiting for you.

There is a simple trick you can use to get notified when your async tasks are finished. The trick is to use dependencies. You have two options here. If you need your operations to execute one after another, you can set the next operation to be dependent on the previous. So when your last operation is finished, your queue is finished as well. This is easy to do.

For concurrent operations(executing at same time),  Create another operation. Operations can have dependencies on multiple operations. So when you create your operations you add them as a dependency to that operation. When all dependent operation finish, your operation will get executed. And this way you can tell that your ‘queue’ is finished. If you think about this from a logical perspective, it makes perfect sense. Anyone can add a bunch of operations in the operation queue, and if you don’t own it completely, you don’t know who added what. So having a callback that will tell you that the queue is empty would not be very useful. Dependencies are baked into the Operations.

func getMovies(onCompleted: (([MovieItem]) -> ())?) {
    
    operationQueue.cancelAllOperations()
    
    var result: [MovieItem] = []
    
    let queueCompletionOperation = BlockOperation {
        onCompleted?(result)
    }
    
    var operations: [Operation] = []
    
    operationQueue.isSuspended = true
    
    for i in 1...5 {
        guard
            let urlString = DataSourceConstants.URLString(forPage: "\(i)")
            else {
                continue
        }
        
        let networkingOperation = GetDataOperation(withURLString: urlString, andNetworkingProvider: networkingProvider)
        let parsingOperation = ParseDataOperation(withFactory: moviesFactory)
        
        networkingOperation.completionBlock = {
            parsingOperation.moviesData = networkingOperation.responseData
        }
        
        parsingOperation.completionBlock = {
            if let moviesArray = parsingOperation.movies {
                DispatchQueue.global().sync(flags: .barrier) {
                    result = result + moviesArray
                }
            }
        }
        
        parsingOperation.addDependency(networkingOperation)
        
        queueCompletionOperation.addDependency(parsingOperation)
        
        operations.append(contentsOf: [parsingOperation, networkingOperation])
    }
    
    operations.append(queueCompletionOperation)
    
    operationQueue.addOperations(operations, waitUntilFinished: false)
    operationQueue.isSuspended = false
}

We have our ‘queueCompletionOperation’ at the top and in the block we’re calling our closure. We suspend the queue before adding new operations and we’re setting the dependency on our queueCompletionOperation to parsingOperation. After the loop is finished, we add all the operations in the queue and un-suspend the queue.


Dispatch queue :

DispatchQueue is an abstraction layer on top of the GCD queue that allows you to perform tasks asynchronously and concurrently in your application. Tasks are always executed in the order they’re added to the queue.
There are two types of dispatch queues :
1. Serial Dispatch Queue
2. Concurrent Dispatch Queue


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


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.

In Objective C, how can avoid crashing of app?

Ans. :

There are multiple aspects to your questions, let me try to answer them:

  • NSSetUncaughtExceptionHandler only catches uncaught exceptions which is only a small subset of possible crashes. 
  • Exceptions in Objective-C are defined to be fatal and it is not recommended to catch them and even more not recommended to run any non-async safe code, which includes any Objective-C and Swift code. 
  • To catch crashes you need to setup signal handlers and then only run async-safe code at the time of the crash, which is only a small subset of C. Especially you may not allocate new memory at crash time at all.

NSSetUncaughtExceptionHandler(&HandleException);
signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);



This will works for most situations.

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.

How to release app to testflight?

Ans :

Q. What is TestFlight?
A. TestFlight is a platform provided by Apple that allows you to send a testable version of your app to specific beta users. It’s important to realise this is different than the App Store (which is available to the general public). Once you send a user a TestFlight invitation, they must download the TestFlight app where they can download and use a specific version of your app for 60 days.

App resource and deployment to TestFlight :

Apple’s Developer Portal. Here you create a distinct IDs for an App, get your certificates and much more.
iTunes Connect is where you manage your app, its details, screenshots, and who all has access to the different types of the app info (like Revenue, and User stats).


  1. Register bundle identifier i.e com.benefit.me on developer.apple.com site. Add capabilities if any.
  2. Develop, Download and Install required certificates (ad hoc distribution for TestFlight). 
  3. In iTunes Connect, register your app with required fields.
  4. Goto TestFlight tab, there is no any builds right now.
  5. Now goto  Xcode and Select generic device and then goto  Product > Archive and Choose valid distribution certificate and upload to App Store. It will only uploaded to iTunes Connect portal.


If you go back to the TestFlight tab and click on the iOS TestFlight Builds sidebar item you will now see that your archive is being processed by iTunes Connect. This should take ~15 mins and you will receive an email when done.

Now that our build is on iTunes Connect we need to set up Internal and/or External TestFlight Testing.

After processing, select version no to send to tester, fill required information about what to test, what types of testers or group app has to be sent for testing. After submit, after  sometime, tester will get email or may get notification about new build with version is ready to test.

BuddyBuild or Hockey App are for alternatives to TestFlight.

Source : Quick Guide - Daniel Mathews

How you show current location blue dot on map?

Ans :

self.mapView.myLocationEnabled = YES to hide the blue dot.
set a class to implement CLLocationManagerDelegate to track user's location.

https://stackoverflow.com/a/40058423