2017-07-10 3 views
0

私は、MapViewで複数の注釈を作成するのに苦労しています。これまでは、関連するクラスを作成して、データをダウンロードし、解析し、使用できる配列に格納することができました。しかし、私はまだ上記のデータを使用してアノテーションを必要とするように苦労しています。サーバからのデータを使用して複数のMapKitアノテーションを作成する方法は?

HomeModelクラス - ダウンロードおよびサーバ

import UIKit 
import Foundation 

protocol HomeModelProtocol: class { 
func itemsDownloaded(items: NSArray) 
} 

class HomeModel: NSObject, URLSessionDataDelegate { 

weak var delegate: HomeModelProtocol! 

var data = Data() 

let urlPath: String = "https://FAKEDATABASEURL.XYZ" 

func downloadItems() { 
    let url: URL = URL(string: urlPath)! 
    let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default) 
    let task = defaultSession.dataTask(with: url) { (data, response, error) in 

     if error != nil { 
      print("Failed to download data") 
     } else { 
      print("Data downloaded") 
      self.parseJSON(data!) 
     } 
    } 
    task.resume() 
} 

func parseJSON(_ data:Data) { 

    var jsonResult = NSArray() 

    do { 
     jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! NSArray 
    } catch let error as NSError { 
     print(error) 
    } 

    var jsonElement = NSDictionary() 
    let locations = NSMutableArray() 

    for i in 0 ..< jsonResult.count { 
     jsonElement = jsonResult[i] as! NSDictionary 
     let location = LocationModel() 

     if let name = jsonElement["Name"] as? String, 
      let address = jsonElement["Address"] as? String, 
      let latitude = jsonElement["Latitude"] as? String, 
      let longitude = jsonElement["Longitude"] as? String { 

      location.name = name 
      location.address = address 
      location.latitude = latitude 
      location.longitude = longitude 
    } 

    locations.add(location) 
} 
    DispatchQueue.main.async(execute: {()-> Void in 
     self.delegate.itemsDownloaded(items: locations) 
    }) 
} 
} 

LocalModelクラスから必要な情報を解析 -

import UIKit 
import Foundation 

class LocationModel: NSObject { 

// Properties 
var name: String? 
var address: String? 
var latitude: String? 
var longitude: String? 

// Empty constructor 
override init() { } 

// Construct with @name, @address, @latitude and @longitude. 
init(name: String, address: String, latitude: String, longitude: String) { 
    self.name = name 
    self.address = address 
    self.latitude = latitude 
    self.longitude = longitude 
} 

// Print the object's current state 
override var description: String { 

    return "Name: \(String(describing: name)), Address:\(String(describing: address)), Latitude: \(String(describing: latitude)), Longitude: \(String(describing: longitude))" 
} 
} 

アプリが使用するアレイにデータを格納しますマップビューコントローラ - アプリケーションのマップを制御する

import UIKit 
import MapKit 
import CoreLocation 

class HotPlacesViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate { 

@IBOutlet weak var mapView: MKMapView! 
var isFirstTime = true 

var locationManager = CLLocationManager() 
let newPin = MKPointAnnotation() 

var selectedLocation:LocationModel? 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view. 

    // Setup the location services delegate in this class. 
    locationManager.delegate = self 

    // This little method requests the users permission for location services whilst in this view controller. 
    if CLLocationManager.authorizationStatus() == .notDetermined { 
     self.locationManager.requestAlwaysAuthorization() 
    let alert = UIAlertController(title: "You can change this option in the Settings App", message: "So keep calm your selection is not permanent. ", 
            preferredStyle: .alert) 

     alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) 

     self.present(alert, animated: true, completion: nil) 
    } 

    locationManager.distanceFilter = kCLDistanceFilterNone 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest 
    locationManager.startUpdatingLocation() 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

} 

// Drops the pin on the users current location. 
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
    mapView.removeAnnotation(newPin) 

    let location = locations.last! as CLLocation 
    let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) 
    if(self.isFirstTime) { 
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)) 

    // Set the region on the map. 
    mapView.setRegion(region, animated: true) 
    self.isFirstTime = false 
    } 

    newPin.coordinate = location.coordinate 
    mapView.addAnnotation(newPin) 

} 
} 
+0

は、あなたの 'locations'配列からすべてのポイントをロードするようにしたいですか? – Subramanian

+0

@Subramanianはい。 –

答えて

0

let locations = NSMutableArray()アレイを他のクラスからアクセスできるようにして、HotPlacesViewControllerクラスでこの配列を使用できるようにします。

HotPlacesViewControllerクラスでは、locationsのデータを保持するプロパティを宣言します。などviewDidLoad()内のデータをロード:複数のアノテーションは、このロジックに従うために、そして、

class HotPlacesViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate { 
    // declare a property which will hold the locations data 
    override func viewDidLoad() { 
     ... 
     ... 
     locations = // load your data here 
    } 
} 

を:

for location in locations { 
    let annotation = MKPointAnnotation() 
    annotation.title = location.name 
    annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude) 
    mapView.addAnnotation(annotation) 

} 
+0

お返事ありがとうございます。しかし、私が二重チェックしたいので、 'locations ='行を入力してください。私はあなたがカバーしていることを確認したいいくつかのステップがあるので、あなたもステップバイステップで行くことができますか? –

+0

'locations = NSMutableArray()として! [LocationModel] 注釈をMKPointAnnotation()にします。 annotation.title = location.name //緯度と経度の値をDoublesに変換します。 let lat = Double((selectedLocation?.latitude)!) let long = Double((selectedLocation?.longitude)!) annotation.title = location.name annotation.coordinate = CLLocationCoordinate2D(latitude:lat !,経度: ) mapView.addAnnotation(annotation)} ' –

+0

私はあなたの道を徹底させましたが、私は自分のデバイスでそれを実行しても、希望する場所のピンは表示されません。 –

関連する問題