ios - Synchronous network calls blocking other calls on startup -


i have app hundreds of different network calls (http requests) rest service. calls done every single page of app , there of them. there requirement 2 requests have done (on startup or awake) before other network requests happens. result of these 2 requests config data needed before other following requests. (this requirement has many reason)

i have 1 central method requests. uses afnetworking , (of course) asynchronous handlers:

func get(path: string, var parameters: dictionary<string, string>? = nil) -> future<anyobject!> {     let promise = promise<anyobject!>()      manager.get(path, parameters: parameters, success: { (task: nsurlsessiondatatask!, response: anyobject!) -> void in         // processing...         promise.success(response)      }) { (task: nsurlsessiondatatask!, error: nserror!) -> void in         // failure handling...         promise.failure(error)     }      return promise.future } 

the problem - how first 2 calls , block other calls until 2 succeed? obvious solution semaphore blocks thread (not main!) until 2 calls arrive if possible want avoid solution. (because of deadlocks, race conditions, how error handling, etc... usual suspects)

so there better solution this?

the synchronous order has be:

  1. 1st call
  2. wait successful response of 1st call
  3. 2nd call
  4. wait or successful response of 2nd call
  5. allow other calls (async) in order

i can not logic on upper layers of app because requests come every part of app, need rewrite everthing. want centrally on single request.

maybe possible promise/future pattern use, hints welcome.

thanks.

there couple of approaches tackle class of problem:

  • you can use gcd (as shown in the answer linked to) using semaphores or dispatch groups.
  • you can use asynchronous nsoperation custom subclass in conjunction nsoperationqueue.
  • or can use promises.

but i'd suggest pick 1 of these three, don't try introduce dispatch/operation queue patterns existing futures/promises code. people suggest dispatch/operation queue approaches because how 1 solves type of problem (using futures not gained popular acceptance yet, , there competing promises/futures libraries out there). promises/futures designed solve precisely problem, , if you're using that, stick it.

on specifics of dispatch/operation approaches, explain why don't gcd approach , try convince use nsoperationqueue approach, that's moot if you're using promises/futures.

the challenge here, though, appear using old version of thomvis/brightfutures. current version takes 2 types generic. code below won't work you. i'll offer as suggestion, may illustrative.

for example, let's imagine had loginurl (the first request), , second request wanted perform after that, had array urls wanted run concurrently respect each other, after first 2 requests done. using 3.2.2 of brightfutures, might like:

get(loginurl).flatmap { responseobject -> future<anyobject!, nserror> in     return self.get(secondrequesturl) }.flatmap { responseobject -> future<int, nserror> in     return urls.map { self.get($0) }.fold(0) { sum, _ in sum + 1 } }.onsuccess { count in     print("\(count) concurrent requests completed successfully") }.onfailure { error in     print("not successful: \(error)") } 

judging code snippet, must using old version of brightfutures, above won't work written, illustrates basic idea. use capabilities of brightfutures manage these asynchronous tasks , control done sequentially , done concurrently.


Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -