2015-10-30 2 views
0

У меня есть следующий метод под названием ViewDidLoad(). Я понимаю, что session.dataTaskWithRequest автоматически запускается в фоновом потоке. И из-за этого код, следующий этому методу в ViewDidLoad(), не дождался завершения этого процесса и начала его выполнения.Функция завершена до NSURLSession - dataTaskWithRequest завершено

Есть ли способ гарантировать, что фоновый поток будет выполнен до того, как будут выполнены другие методы?

func getCoordinatesFromServer() { 
     let request = NSMutableURLRequest(URL: NSURL(string: constants.urlName.loadData)!) 
     request.HTTPMethod = "POST" 
     request.addValue("multipart/form-data", forHTTPHeaderField: "Accept") 
     request.setValue("keep-Alive", forHTTPHeaderField: "Connection") 
     request.HTTPBody = (constants.requestTag.getCoordinates).data 

     let session = NSURLSession.sharedSession() 
     let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in 
      if let response = response { 
       let httpResponse = response as! NSHTTPURLResponse 

       print("response code = \(httpResponse.statusCode)") 
       if (httpResponse.statusCode == 200) { 
        dispatch_async(dispatch_get_main_queue(), { 
         let decodedData = NSData(base64EncodedData: data!, options: NSDataBase64DecodingOptions([])) 
         let jsonText = NSString(data: decodedData!, encoding: NSASCIIStringEncoding) as! String 
         do { 
         let json = try NSJSONSerialization.JSONObjectWithData(jsonText.data, options: NSJSONReadingOptions.init(rawValue: 0)) 
         self.parseJsonData(json["Datalist"] as! NSArray) 
         } catch { 
         print("Error:\n \(error)") 
         } 
        }) 
       } 
      } 
     }) 
     task.resume() 
    } 

С уважением,

+0

Название ссылки для NSURLConnection, но это та же самая техника, в которой вы нуждаетесь. – Moritz

ответ

1

, если я понимаю ваш вопрос, вы можете решить эту проблему на этом пути Например:

class func ConnectedToNetwork(completionHandler: ((Status: Bool) -> Void)) 
    { 
    let url = NSURL(string: "http://google.com") 
    let request = NSMutableURLRequest(URL: url!) 
    request.HTTPMethod = "HEAD" 
    request.timeoutInterval = 0.2 
     let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data,response, error) in 
      let httpResponse = response as! NSHTTPURLResponse 
       if httpResponse.statusCode == 200 
       { completionHandler(Status: true) 
        return 
       } 
     } 
     task.resume() 
    } 

, а затем вы можете работать с этим

Checks.ConnectedToNetwork({ Status in dispatch_async(dispatch_get_main_queue()) 
     { 
      if Status == true 
      { 
       //do what you want 
      } 
}); 
0

dataTaskWithRequest является assync вызов, и он имеет completionHandler блок. Так весь код, который вы написали внутри будет выполняться после того, как задача данных закончена:

let request = NSURLRequest(URL: NSURL(string: "http://google.com")!) 
let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {(data, response ,error) in 
    print("3") // executed after data task is finished 
    print("4") // executed after data task is finished 
}) 
task.resume() 
print("1") 
print("2") 
+0

Спасибо за ваше время, отвечая на него. Я понимаю, что обработчик завершения вызывается после завершения задачи по данным. Мой вопрос: «Если мне нужно использовать этот метод dataTaskWithRequest» в методе ViewDidLoad(), как я должен обеспечить, чтобы обработчик завершения выполнялся до выполнения других методов. – PK20

+0

переместите эти методы в раздел 'viewDidLoad' – katleta3000

+0

Это не похоже на хорошее решение. Я не уверен, поняли ли вы мой вопрос или нет. – PK20

-1
import Foundation 

// some aync function with completition handler, i MUST USE AS IT IS 
func f(completitionHandler:()->()) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {() -> Void in 
     print("running concurrently") 
     sleep(1) 
     print("finished") 
     completitionHandler() 
    } 
} 

// some function running on main queue 
func foo() { 
    // create dispatch group 
    let group = dispatch_group_create() 
    let myCompletitionHandler:()->() = { 
     dispatch_group_leave(group) 
    } 
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) 
    dispatch_group_async(group, queue) {() -> Void in 
     dispatch_group_enter(group) 
     f(myCompletitionHandler) 
    } 
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER) 
} 

foo() 
print("foo finished") 

это не лучший вообще, тем лучше Solut ion должен запускать синхронную версию f() вместо этого «обходного пути» :-)

+0

PK20 спрашивает: «Как я должен обеспечить, чтобы обработчик завершения выполнялся перед выполнением других методов». Я не понимаю, почему кто-то жалуется на мой ответ ... Я не говорю, что это «wokraround» - лучшая практика программистов. Я просто пытаюсь объяснить, как ждать дальнейшего выполнения программы, пока не закончится весь асинхронный код. что не так с моим ответом? Кстати, эта техника иногда может быть очень полезной ... – user3441734

Смежные вопросы