2017-03-29 8 views
-2

注釈配列を返そうとしていますが、return文で以下のエラーが表示されます。私はいくつかの研究を行ってしている予期しない非無効値In Void関数(Swift 3.0)

無効機能で

予期しない非空値は、私が完了ハンドラ内で、返却しようとしている可能性がありますが、周りの道を見つけるように見えることはできませんことを発見しましたそれ。この機能の

func getAnnotations() { 

    //The php file connects the Database and Swift 
    let request = NSMutableURLRequest(url: NSURL(string: "https://test.com/pull.php")! as URL) 

    //Receiver's HTTP request method 
    request.httpMethod = "POST" 

    let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     old_data, response, error in 

     //Error Checking 
     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     //Response string built up 
     let responseString = NSString(data: old_data!, encoding: String.Encoding.utf8.rawValue) 
     print("responseString = \(responseString)") 

     //Manipulating JSON data 
     do { 
      if let new_data = old_data, 
      let json = try JSONSerialization.jsonObject(with: new_data) as? [String: Any], 
      let buildings = json["buildings"] as? [[String: Any]] { 

       var annotations: [ARAnnotation] = [] 

       for building in buildings { 

        let BUILDING_ID = "BuildingID" 
        let BUILDING_NAME = "BuildingName" 
        let BUILDING_INFO = "BuildingInfo" 
        let BUILDING_LAT = "Latitude" 
        let BUILDING_LNG = "Longitude" 

        let IdString:String = building[BUILDING_ID] as! String 
        let NameString:String = building[BUILDING_NAME] as! String 
        let InfoString:String = building[BUILDING_INFO] as! String 

        let LatString:String = building[BUILDING_LAT] as! String 
        let LatDouble:Double = Double(LatString)! 

        let LngString:String = building[BUILDING_LNG] as! String 
        let LngDouble:Double = Double(LngString)! 

        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(LatDouble, LngDouble) 

        let annotation = ARAnnotation() 
        annotation.location = CLLocation(latitude: LatDouble, longitude: LngDouble) 
        annotation.title = "POI: \(NameString)" 
        annotations.append(annotation) 

        return annotations 
        //error 
       } 
      }  
     } catch { 
      print(error) 
     } 
    } 
    task.resume() 
} 

私の目標は、私のデータ(注釈、場所、NameString、InfoStringを...)を保持する変数を引き出し、別の関数でそれらを使用できるようにすることです。

単純なリターンではなく、別の方法がある場合は、私が聞きたいのですが。

ありがとうございます。

答えて

0

これはネットワークタスクです。何も返さないでください。なぜなら、データをロードするのに時間がかかるから、関数を呼び出すときには常に空の配列が得られるからです。

func getAnnotations(completion: @escaping (_ annotations: [ARAnnotation], _ error: Error?) -> Void) { 

    //The php file connects the Database and Swift 
    let request = NSMutableURLRequest(url: NSURL(string: "https://test.com/pull.php")! as URL) 

    //Receiver's HTTP request method 
    request.httpMethod = "POST" 

    let task = URLSession.shared.dataTask(with: request as URLRequest) { 
     old_data, response, error in 

     //Error Checking 
     if error != nil { 
      print("error=\(error)") 
      return 
     } 

     //Response string built up 
     let responseString = NSString(data: old_data!, encoding: String.Encoding.utf8.rawValue) 
     print("responseString = \(responseString)") 

     //Manipulating JSON data 
     do { 
      if let new_data = old_data, 
       let json = try JSONSerialization.jsonObject(with: new_data) as? [String: Any], 
       let buildings = json["buildings"] as? [[String: Any]] { 

       var annotations: [ARAnnotation] = [] 

       for building in buildings { 

        let BUILDING_ID = "BuildingID" 
        let BUILDING_NAME = "BuildingName" 
        let BUILDING_INFO = "BuildingInfo" 
        let BUILDING_LAT = "Latitude" 
        let BUILDING_LNG = "Longitude" 

        let IdString:String = building[BUILDING_ID] as! String 
        let NameString:String = building[BUILDING_NAME] as! String 
        let InfoString:String = building[BUILDING_INFO] as! String 

        let LatString:String = building[BUILDING_LAT] as! String 
        let LatDouble:Double = Double(LatString)! 

        let LngString:String = building[BUILDING_LNG] as! String 
        let LngDouble:Double = Double(LngString)! 

        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(LatDouble, LngDouble) 

        let annotation = ARAnnotation() 
        annotation.location = CLLocation(latitude: LatDouble, longitude: LngDouble) 
        annotation.title = "POI: \(NameString)" 
        annotations.append(annotation) 

        completion(annotations, nil) 
        //error 
       } 
      }  
     } catch { 
      print(error) 
      completion([], error) 
     } 
    } 
    task.resume() 
} 

そして、このようにそれを使用します:

getAnnotations() { (annotations, error) in 

    // TODO: something 
    print("annotations: \(annotations), error: \(error)") 
} 
+0

それでもクロージャを理解しようと、このように、完了ハンドラとしてクロージャを使用してみましょう。あなたはあなたの応答の最後の部分を使う方法を説明できますか? @Danh Huynh –

+0

はい、そのような 'getAnnotations'関数を呼び出すべきです。タスクが完了すると、 'annotations'の配列を返します。 –

関連する問題