2017-08-31 2 views
0

J'ai créé un fichier de mise en réseau pour le téléchargement de données et je souhaite affecter les données à un autre contrôleur de vue afin de remplir une carte avec des annotations. Le téléchargement des données a réussi, mais je n'arrive pas à l'attribuer au contrôleur de vue. Je peux seulement le faire fonctionner quand j'inclue le code de gestion de réseau dans le contrôleur de vue et utilise DispatchQueue.main.async. Je veux garder le fichier réseau et voir le contrôleur séparé. Toute idée serait grandement appréciée. Excuses d'avance pour les nombreuses lignes de code.Affectation de données à l'aide de Grand Central Dispatch Swift 3

Le fichier de mise en réseau est la suivante:

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() 
    } 
} 

Le modèle est le suivant:

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 

    } 
} 

Le contrôleur de vue est le suivant:

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) 

    } 
} 
+0

vous pouvez utiliser 'NotificationCenter' pour le faire. Pour en savoir plus sur 'NotificationCenter', consultez https://developer.apple.com/documentation/foundation/notificationcenter – Venkat

Répondre

1

Vous exécutez des blocs d'achèvement seulement dans les cas d'échec. Exécutez le bloc d'achèvement une fois que vous avez réussi à analyser les données et passez le tableau en paramètre à 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() 
    } 
} 

Peu plus d'erreurs dans votre code:

  1. Votre bloc d'achèvement prévoit emplacement en tant que paramètre. mais dans votre code, vous créez un tableau de lieux.

    let emplacement: [Localisation] = []

J'ai donc modifié les paramètres du bloc d'achèvement de retourner réseau d'emplacements

  1. Dans votre pour boucle vous créez

    var dictionnaire = [_id, nom, ImageID, catégorie, détails, latitude, longitude] comme [Tous]

et en l'ajoutant à dictionary.append (emplacement) Je n'ai aucune idée de ce que ce code est. Je crois que ce que tu en train d'essayer de faire est de créer un objet de localisation à partir des données, puis ajoutez-le à l'emplacement tableau

location.append(your_new_location_object) 

Hope it helps

+1

J'ai modifié le code et cela fonctionne maintenant. –

+0

@ j-hooper: Je suis content d'avoir résolu le problème :) Codage heureux –