使用 Grand Central Dispatch 分配数据 Swift 3

Assign Data using Grand Central Dispatch Swift 3

我创建了一个用于下载数据的网络文件,我想将数据分配给另一个视图控制器,这样我就可以用注释填充地图。数据下载成功,但我无法将其分配给视图控制器。只有当我在视图控制器中包含网络代码并使用 DispatchQueue.main.async 时,我才能让它工作。我想将网络文件和视图控制器分开。任何见解将不胜感激。提前为多行代码道歉。

联网文件如下:

import UIKit

class Networking {

static let shared = Networking()

var objects = [Any]()

func getData (_ completionHandler:@escaping (Location?) -> ()) {

    //Create the url with NSURL reuqest
    let url = URL(string: "http://localhost:3000/locations")

    let request = NSMutableURLRequest(url: url! as URL)

    //Set HTTP method as GET
    request.httpMethod = "GET"

    //HTTP Headers
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    //Create dataTask using the session object to send data to the server
    URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in

        guard let data = data,
            let dataStore = String(data: data, encoding: String.Encoding.utf8) else {
                print("Could not find network")
                completionHandler(nil)
                return
        }

        guard error == nil else {
            print("Error calling GET")
            completionHandler(nil)
            return
        }

        let HTTPResponse = response as! HTTPURLResponse
        let statusCode = HTTPResponse.statusCode

        if (statusCode == 200) {
            print("Files downloaded successfully. \(dataStore)" )
        } else {
            completionHandler(nil)
            return
        }

        //Create json object from data
        do {

            let json = try! JSONSerialization.jsonObject(with: data , options: []) as? [[String: Any]]
let location: [Location] = []

            if let array = json {

                for i in 0 ..< array.count {

                    if let data_object = array[i] as? [String: Any] {

                        if let _id = data_object["_id"] as? String,
                            let name = data_object["name"] as? String,
                            let imageID = data_object["imageID"] as? String,
                            let category = data_object["category"] as? String,
                            let details = data_object["details"] as? String,
                            let latitude = data_object["latitude"] as? Double,
                            let longitude = data_object["longitude"] as? Double {

                            var dictionary  = [_id, name, imageID, category, details, latitude, longitude] as [Any]

                            dictionary.append(location)

                        }
                    }
                } 
             }  
         }

        }.resume()
    }
}

模型如下:

class Location {

var _id : String
var name : String
var imageID : String
var category : String
var details : String
var latitude : Double
var longitude : Double

init?(_id: String, name: String, imageID: String, category: String, details: String, latitude: Double, longitude: Double) {

    self._id = _id
    self.name = name
    self.imageID = imageID
    self.category = category
    self.details = details
    self.latitude = latitude
    self.longitude = longitude

  }
}

视图控制器如下:

 class MapViewController: UIViewController, MGLMapViewDelegate, UIGestureRecognizerDelegate {

 override func viewDidLoad() {
    super.viewDidLoad()

    mapView.delegate = self


    Networking.shared.getData { (locations) in


    }

    populateMap()

}

func populateMap (){

    let point = MGLPointAnnotation()
    for location in locations {
        let coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude )
        point.coordinate = coordinate
        point.title = location.name
        point.subtitle = location.category
        self.mapView.addAnnotation(point)

    }
}

您仅在失败情况下才执行完成块。成功解析数据并将数组作为参数传递给 closure/block.

后执行完成块
import UIKit

class Networking {

static let shared = Networking()

var objects = [Any]()

func getData (_ completionHandler:@escaping ([Location]?) -> ()) {

    //Create the url with NSURL reuqest
    let url = URL(string: "http://localhost:3000/locations")

    let request = NSMutableURLRequest(url: url! as URL)

    //Set HTTP method as GET
    request.httpMethod = "GET"

    //HTTP Headers
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    //Create dataTask using the session object to send data to the server
    URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in

        guard let data = data,
            let dataStore = String(data: data, encoding: String.Encoding.utf8) else {
                print("Could not find network")
                completionHandler(nil)
                return
        }

        guard error == nil else {
            print("Error calling GET")
            completionHandler(nil)
            return
        }

        let HTTPResponse = response as! HTTPURLResponse
        let statusCode = HTTPResponse.statusCode

        if (statusCode == 200) {
            print("Files downloaded successfully. \(dataStore)" )
        } else {
            completionHandler(nil)
            return
        }

        //Create json object from data
        do {

            let json = try! JSONSerialization.jsonObject(with: data , options: []) as? [[String: Any]]
let location: [Location] = []

            if let array = json {

                for i in 0 ..< array.count {

                    if let data_object = array[i] as? [String: Any] {

                        if let _id = data_object["_id"] as? String,
                            let name = data_object["name"] as? String,
                            let imageID = data_object["imageID"] as? String,
                            let category = data_object["category"] as? String,
                            let details = data_object["details"] as? String,
                            let latitude = data_object["latitude"] as? Double,
                            let longitude = data_object["longitude"] as? Double {

                            var dictionary  = [_id, name, imageID, category, details, latitude, longitude] as [Any]

                            dictionary.append(location) //am not sure of what this means test your code

                            completionHandler(location)
                        }
                    }
                } 
             }  
         }

        }.resume()
    }
}

您的代码中还有一些错误:

  1. 您的完成块需要 Location 作为参数。但在您的代码中,您正在创建一个位置数组。

    让位置:[位置] = []

所以我已经将完成块参数修改为return位置数组

  1. 在您的 for 循环中,您正在创建

    var dictionary = [_id, name, imageID, category, details, latitude, longitude] 作为[Any]

并将其附加到 dictionary.append(location) 我不知道这段代码是什么。我相信你实际上想做的是从数据创建一个位置对象,然后将它添加到位置数组

location.append(your_new_location_object)

希望对您有所帮助