我创建了一个用于下载数据的Networking文件,我想将数据分配给另一个视图控制器,这样我就可以用注释填充地图。数据下载成功,但我无法将其分配给视图控制器。只有当我在视图控制器中包含网络代码并使用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)
}
}
您只在失败的情况下执行完成块。一旦您成功解析了数据并将数组作为参数传递给闭包/块,就执行完成块。
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()
}
}
代码中再出现几个错误:
您的完成块需要Location作为参数。但在您的代码中,您正在创建一个位置数组。
let location:[location]=[]
所以我修改了完成块参数以返回位置数组
在for循环中,您正在创建
var dictionary=[_id,name,imageID,category,details,纬度,经度]as[Any]
并将其附加到dictionary.append(location(我不知道这段代码是什么。我相信你实际上想做的是从数据中创建一个位置对象,然后将其添加到位置数组
location.append(your_new_location_object)
希望它能帮助