2016-05-18 110 views
-2

我對GET請求的方法在我的代碼:如何使一個同步GET請求

func makeHTTPGetRequest(path: String, parameters: [String: AnyObject], completionHandler: (NSData?, NSURLResponse?, NSError?) -> Void) -> NSURLSessionTask { 

    let parameterString = parameters.stringFromHttpParameters() 
    let requestURL = NSURL(string:"\(path)?\(parameterString)")! 

    let request = NSMutableURLRequest(URL: requestURL) 
    request.HTTPMethod = "GET" 
    request.setValue("Bearer " + userInfoDefaults.stringForKey("accessToken")!, forHTTPHeaderField: "Authorization") 

    let session = NSURLSession.sharedSession() 
    let task = session.dataTaskWithRequest(request, completionHandler:completionHandler) 
    task.resume() 

    return task 
    } 

這是由用於填充在一個特定的場景選擇器視圖的另一種方法叫做:

func getAffiliateds() -> [String]? { 
    var affiliateds:[String] = [] 
    makeHTTPGetRequest(baseURL + "affiliateds", parameters: [:], completionHandler: { (data, response, error) in 
     do { 
     affiliateds = try NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! [String] 
     print (affiliateds) 
     } 
     catch { print("Error: \(error)") } 
    }) 
    return affiliateds 
    } 

我需要從我的web服務獲取所有關聯,然後將其列在選取器視圖中。但是當我調試代碼時,我發現關聯首先作爲一個空數組返回,然後返回正確的信息。只有當它已經從web服務接收到數據時,我才需要從getAffiliateds返回數組。我怎樣才能做到這一點?

+0

異步代碼不能稱爲同步。 – Sulthan

+0

對不起。不明白。我剛剛在一個月前開始使用Swift編程。你能否告訴我,我需要更改我的代碼以使請求異步? – chr0x

+0

@Charles - 'getAffiliateds'不應該嘗試返回數據。將填充選擇列表的代碼移動到getAffiliateds中的'completionHandler'中(或重複'completionHandler'模式,並調用'getAffiliateds'來執行這個過程)。 – Rob

回答

1

你不能。您的getAffiliateds()不能返回值取決於它將運行的異步代碼。這就是異步代碼的本質。相反,執行在完成處理某種回調時,它被稱爲:

makeHTTPGetRequest(baseURL + "affiliateds", parameters: [:], completionHandler: { (data, response, error) in 
    do { 
    affiliateds = try NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! [String] 
    print (affiliateds) 
    // DO SOMETHING HERE 
    } 
} 

一個常見的策略是呼叫者提供另一個完成處理這這個完成處理程序將調用。

+1

並且請做一個搜索,因爲這已經在堆棧溢出已經無數次的討論和解釋。 – matt

+0

我會的。並感謝您的回答:) – chr0x

1

你有一個例行:

func getAffiliateds() -> [String]? { 
    var affiliateds:[String] = [] 
    makeHTTPGetRequest(baseURL + "affiliateds", parameters: [:], completionHandler: { (data, response, error) in 
     do { 
      affiliateds = try NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! [String] 
      print (affiliateds) 
     } 
     catch { print("Error: \(error)") } 
    }) 
    return affiliateds 
} 

而且你可能有一些代碼,不會是這樣的:

func populatePicklist() { 
    let affiliateds = getAffiliateds() 
    // populate picklist here 
} 

你應該更改爲:

func getAffiliatedsWithCompletionHandler(completionHandler: ([String]?) ->()) { 
    makeHTTPGetRequest(baseURL + "affiliateds", parameters: [:]) { data, response, error in 
     do { 
      let affiliateds = try NSJSONSerialization.JSONObjectWithData(data!, options:[]) as? [String] // two notes here: first, define local var here, not up above; second, use `as?` to gracefully handle problems where result was not `[String]` 
      print (affiliateds) 
      completionHandler(affiliateds) 
     } 
     catch { 
      print("Error: \(error)") 
      completionHandler(nil) 
     } 
    } 
} 

func populatePicklist() { 
    getAffiliatedsWithCompletionHandler { affiliateds in 
     // populate picklist here 
    } 

    // but not here 
}