2016-09-24 67 views
2

昨天我更新了新的Mac OS X Sierra和XCode 8,這迫使我更新到Swift 3.0語法。在我的應用我有類似下面的許多功能:Swift3的許多問題:無法理解完成處理程序的新語法

fileprivate func requestFisheFieldWithHandler(_ url:String, completionHandler: @escaping (_ success: NSDictionary?, _ error: NSError?) -> Void) { 

    let configuration = URLSessionConfiguration.default 

    let url: URL = URL(string: url)! 
    let urlRequest: URLRequest = URLRequest(url: url) 

    let session = URLSession(configuration: configuration) 

    let task = session.dataTask(with: urlRequest, completionHandler: { (data: Foundation.Data?, response: URLResponse?, error: NSError?) -> Void in 

     if (error != nil) { 
      //print(error?.code) 
      //print(error) 
      completionHandler(success: nil, error: error) 
     } 

     else { 
      do { 
       let responseJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [String: String] 
       completionHandler(success: responseJSON, error:nil) 
      } 
      catch let error as NSError { 
       completionHandler(success: nil, error:error) 
      } 
     } 
    } as! (Data?, URLResponse?, Error?) -> Void) 

    task.resume() 
} 

,我得到這個錯誤:

"Cannot convert value of type '(Data?, URLResponse?, Error?) -> Void' to expected argument type '(Data?, URLResponse?, Error?) -> Void'"

此外,我還使用了許多關聯數組從下載的JSON文件中收集數據,如以下:

for comune in response! { 
         self.comuni.append(comune["nome"] as! String) 
         self.comuniWithID[comune["nome"] as! String] = Int(comune["idcomune"] as! String) 
} 
DispatchQueue.main.async { 
    self.myPicker.reloadComponent(1) 
} 

和其他錯誤我得到的是:

"Type 'NSFastEnumerationIterator.Element' (aka 'Any') has no subscript members"

請有人幫我糾正它們嗎?因爲我不明白他們的意思,我的應用程序將被下一個9月30日公佈的...

+0

我發現Swift3很難拿起...感謝那些推動社會:) –

回答

5

最顯著的變化是,所有的參數標籤中關閉已在斯威夫特除去3

這是你的代碼斯威夫特3兼容。

一如既往,不要將Swift集合類型轉換爲基礎對象。你會扔掉所有類型的信息。

並且不要在完成塊中使用註釋返回值,編譯器可以推斷出類型。如果您需要查找實際類型→點擊上的符號。

fileprivate func requestFisheFieldWithHandler(_ url:String, completionHandler: @escaping ([String: String]?, NSError?) -> Void) { 

    let configuration = URLSessionConfiguration.default 

    let url: URL = URL(string: url)! 
    let urlRequest = URLRequest(url: url) 

    let session = URLSession(configuration: configuration) 

    let task = session.dataTask(with: urlRequest) { (data, response, error) -> Void in 
    if (error != nil) { 
     completionHandler(nil, error as NSError?) 
    } 

    else { 
     do { 
     let responseJSON = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [String: String] 
     completionHandler(responseJSON, nil) 
     } 
     catch let error as NSError { 
     completionHandler(nil, error) 
     } 
    } 
    } 
    task.resume() 
} 

關於你要投response!到的東西比Any更有意義的第二個錯誤,我想... in response as! [[String:Any]]

+0

謝謝你的隊友。非常善於幫助我更好地理解這些消息。最後,我成功地糾正了一切。非常感謝!我不會再爲蘋果開發應用程序......這是不可接受的,他們經常改變標準...... –

+1

給Swift一個機會。這是一種相對年輕的語言,可能還沒有成長;-) – vadian

+0

我已經給Swift 3次以上的機會......這是他們第三次在我準備發佈應用程序時改變標準。最糟糕的是,當強迫網絡連接使用TLS時,我不得不懇求我的實驗室技術人員爲我的團隊的服務器取得證書......我厭倦了讓這麼緊張...... –

1

dataTask(with:completionHandler:)斯威夫特3完成處理器更改爲completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void所以使用Error代替NSError

let task = session.dataTask(with: urlRequest, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in 

更多關於完成處理程序檢查Apple Documentation

對於您的錯誤

Type 'NSFastEnumerationIterator.Element' (aka 'Any') has no subscript members"

你需要指定響應的類型[[String:Any]]然後一切都正常。

if let array = response as? [[String: Any]] { 
    for comune in array { 
     self.comuni.append(comune["nome"] as! String) 
     self.comuniWithID[comune["nome"] as! String] = Int(comune["idcomune"] as! String) 
    } 
} 
+1

謝謝你的隊友。非常善於幫助我更好地理解這些消息。最後,我成功地糾正了一切。非常感謝!我不再爲蘋果開發應用程序......這是不可接受的,他們經常更改標準... –

+0

@LoryLory您還有一個選項可以使用Objective C。 –