Swift 4 ile Haritalar ve Navigasyon Kullanımı(MapKit)

Uygulamalarımız da ihtiyacımız olan haritaları ve navigasyonu kullanımını nasıl yapabileceğimizi makalemde anlatmaya çalışacağım. Daha iyi anlaşılabilmesi için Seyahat Defterim adlı bir uygulama yaparak anlamaya çalışalım. Uygulamamızın genel mantığı kişinin konumunu haritada göstererek istediği yeri seçmesini sağlayacağız daha sonra bu yeri Core Data kullanarak kayıt edeceğiz. Kayıt edilen verileri seçtiği zamanda navigasyon oluşturarak gitmesini sağlayacağız. Uygulamada Core Data kullanacağımız için CoreData kullanımının anlatıldığı makaleye buraya tıklayarak göz atabilirsiniz.
Öncelikle Create a new Xcode project >> Single View App diyoruz ve projemizin ismini yazıp Use Core Data seçeneğini seçip projemizi oluşturuyoruz.
Projemizi oluşturduktan sonra veritabanımızı şemasını oluşturmamız gerekiyor. projenin_adı.xcdatamodeld adlı klasörümüzü açıp aşağıdaki resimde olacak şekilde ayarlamalarımızı yapıyoruz.
Veritabanı modelimizi oluşturduğumuza göre Info.plist dosyamıza gelip sağ tıklayıp Add Row diyerek “Privacy – Location When In Use Usage Description” fotoğraf galerisine ulaşma iznini ekliyoruz.
Artık uygulamamızı nasıl yapacağımıza gelelim Main.storyboard dosyasını açıp aşağıdaki gibi dizayn ediyoruz.
Favori yerinizin adını, yorumunuzu ve konumunu yerEkleVC.swift dosyasında kayıt ediyoruz.
yerEkleVC.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
// // ViewController.swift // SeyehatDefterim // // Created by Esat Gözcü on 28.11.2017. // Copyright © 2017 Esat Gözcü. All rights reserved. // import UIKit import MapKit //Kullanıcının yerini tespit etmek için kütüphaneyi import ediyoruz import CoreLocation //Kullanıcının favori yerlerini kayıt etmek için import ediyoruz import CoreData class yerEkleVC: UIViewController ,MKMapViewDelegate ,CLLocationManagerDelegate{ //Kullanıcının yerini tespit etmeye yarayan fonksiyon var locationManager = CLLocationManager() @IBOutlet weak var mapView: MKMapView! @IBOutlet weak var yorumText: UITextField! @IBOutlet weak var yerText: UITextField! //Navigasyon oluşturmamıza yarayan fonksiyon var requestCLLocation = CLLocation() var Latitudesecilen = Double() var Longitudesecilen = Double() var secilenYerAdı = "" var secilenYerYorum = "" var secilenYerLongitude :Double = 0 var secilenYerLatitude : Double = 0 override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self locationManager.delegate = self //Doğruluğunu belirliyoruz //Ancak ne kadar doğru yer tespiti yaparsa o kadar pil harcar locationManager.desiredAccuracy = kCLLocationAccuracyBest //locationManager.requestAlwaysAuthorization() sürekli yer değişikliğini takip eder //Sadece istediğimizde zaman yerini tespit eder locationManager.requestWhenInUseAuthorization() //Başlatıyoruz locationManager.startUpdatingLocation() //Kullanıcı ekrana uzun süre bastığında.. let recognizer = UILongPressGestureRecognizer(target: self, action: #selector(yerEkleVC.chooseLocation(gestureRecognizer:))) //En az kaç saniye basarsa recognizer.minimumPressDuration = 2 //mapView'e ekliyoruz mapView.addGestureRecognizer(recognizer) if secilenYerAdı != ""{ //Diğer sayfada bir yer seçilirse verilere göre pin oluşturuyoruz let annotation = MKPointAnnotation() let coordinate = CLLocationCoordinate2D(latitude: self.secilenYerLatitude, longitude: self.secilenYerLongitude) annotation.coordinate = coordinate annotation.title = self.secilenYerAdı annotation.subtitle = self.secilenYerYorum self.mapView.addAnnotation(annotation) yerText.text = self.secilenYerAdı yorumText.text = self.secilenYerYorum } } @objc func chooseLocation(gestureRecognizer : UILongPressGestureRecognizer) { //Ekrana en az 3 saniye basılı tutulduğunda pin oluşturmak için.. if gestureRecognizer.state == UIGestureRecognizerState.began { //Dokunulan noktayı oluşturuyoruz let touchedPoint = gestureRecognizer.location(in: self.mapView) //Dokunduğumuz noktayı convert ediyoruz let chosenCoordinates = self.mapView.convert(touchedPoint, toCoordinateFrom: self.mapView) Latitudesecilen = chosenCoordinates.latitude Longitudesecilen = chosenCoordinates.longitude //Pin oluşturuyoruz let annotation = MKPointAnnotation() annotation.coordinate = chosenCoordinates annotation.title = yerText.text annotation.subtitle = yorumText.text self.mapView.addAnnotation(annotation) } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { //Bulunan konumun enlem ve boylam değerlerini tespit ediyoruz let location = CLLocationCoordinate2D(latitude: locations[0].coordinate.latitude, longitude: locations[0].coordinate.longitude) //Ne kadar zoom yapacağımızla alakalı isterseniz değiştirebilirsiniz let span = MKCoordinateSpan(latitudeDelta: 0.04, longitudeDelta: 0.04) //Haritaya neresi ve ne kadar zoom yapacağını ekledim let region = MKCoordinateRegion(center: location, span: span) //Başlatıyoruz mapView.setRegion(region, animated: true) } func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { //Pin'lerimizi özelleştirip yanına bir tane navigasyona gitmek için buton ekliyoruz if annotation is MKUserLocation { return nil } let reuseID = "myAnnotation" var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseID) as? MKPinAnnotationView if pinView == nil { pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID) pinView?.canShowCallout = true //pin'in rengini belirliyoruz pinView?.pinTintColor = UIColor.red //pin'in yanına bir buton yerleştiriyoruz let button = UIButton(type: UIButtonType.detailDisclosure) pinView?.rightCalloutAccessoryView = button } else { pinView?.annotation = annotation } return pinView } func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { //Pine tıkladığımızda yan tarafta oluşan butona bastığımızda navigasyona gitmesini sağlıyoruz if secilenYerLatitude != 0 { if secilenYerLongitude != 0{ self.requestCLLocation = CLLocation(latitude: secilenYerLatitude, longitude: secilenYerLongitude) } } CLGeocoder().reverseGeocodeLocation(requestCLLocation) { (placemarks, error ) in if let placemark = placemarks { if placemark.count > 0 { let newPlacemark = MKPlacemark(placemark: placemark[0]) let item = MKMapItem(placemark: newPlacemark) item.name = self.secilenYerAdı let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] item.openInMaps(launchOptions: launchOptions) } } } } @IBAction func ekleButton(_ sender: Any) { //Yerlerimizi CoreData'ya kayıt ediyoruz let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext //"Yerler" Entitie'mizi bağlıyoruz let yeniYerler = NSEntityDescription.insertNewObject(forEntityName: "Yerler", into: context) //Verilerimiz ekliyoruz yeniYerler.setValue(yerText.text, forKey: "yer") yeniYerler.setValue(yorumText.text, forKey: "yorum") yeniYerler.setValue(Longitudesecilen, forKey: "longitude") yeniYerler.setValue(Latitudesecilen, forKey: "latitude") do { try context.save() print("saved") } catch{ print("error") } //Ekleme işlemini yaptıktan sonra anasayfaya yönlendiriyoruz self.navigationController?.popViewController(animated: true) } } |
yerlerVC.swift dosyamızda CoreData’dan çektiğimiz yerlerin ismini tableView’de gösteriyoruz.
yerlerVC.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
// // yerlerVC.swift // SeyehatDefterim // // Created by Esat Gözcü on 28.11.2017. // Copyright © 2017 Esat Gözcü. All rights reserved. // import UIKit import CoreData class yerlerVC: UIViewController , UITableViewDelegate , UITableViewDataSource{ @IBOutlet weak var tableView: UITableView! var yerArray = [String]() var yorumArray = [String]() var latitudeArray = [Double]() var longitudeArray = [Double]() var secilenYerAdı = "" var secilenYerYorum = "" var secilenYerLongitude :Double = 0 var secilenYerLatitude : Double = 0 override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self verileriGetir() } override func viewWillAppear(_ animated: Bool) { //override ettiğimiz fonksiyon her sayfa çalıştığında çalışır //Kayıt yaptıktan sonra tekrar gelince güncelleme yapmak için tekrarda fonksiyonumuzu çalıştırıyoruz verileriGetir() } func verileriGetir() { //Core Dataya verileri ekliyoruz let appDelegate = UIApplication.shared.delegate as! AppDelegate //Appdelegate'deki core data için oluşturulan fonksiyona erişiyoruz let context = appDelegate.persistentContainer.viewContext //Verileri "Yerler" entities'ten çekiyoruz let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Yerler") request.returnsObjectsAsFaults = false do { let results = try context.fetch(request) if results.count > 0 { //Arraylarimizi temizliyoruz self.yerArray.removeAll(keepingCapacity: false) self.yorumArray.removeAll(keepingCapacity: false) self.latitudeArray.removeAll(keepingCapacity: false) self.longitudeArray.removeAll(keepingCapacity: false) for result in results as! [NSManagedObject] { //Arraylere verilerimizi ekliyoruz if let yer = result.value(forKey: "yer") as? String{ self.yerArray.append(yer) } if let yorum = result.value(forKey: "yorum") as? String{ self.yorumArray.append(yorum) } if let latitude = result.value(forKey: "latitude") as? Double{ self.latitudeArray.append(latitude) } if let longitude = result.value(forKey: "longitude") as? Double{ self.longitudeArray.append(longitude) } self.tableView.reloadData() } } } catch{ print("error") } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { //tableView'de kaç satır gözükeceğini belirliyoruz return yerArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell() cell.textLabel?.text = yerArray[indexPath.row] return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { //tableView'de bir yer seçildiği zaman değişkenlere o yerin bilgilerini aktarıyoruz secilenYerAdı = yerArray[indexPath.row] secilenYerYorum = yorumArray[indexPath.row] secilenYerLongitude = longitudeArray [indexPath.row] secilenYerLatitude = latitudeArray[indexPath.row] performSegue(withIdentifier: "segue", sender: nil) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { //Diğer sayfaya favori yerin bilgilerini aktarıyoruz if segue.identifier == "segue" { let destinationVC = segue.destination as! yerEkleVC destinationVC.secilenYerAdı = self.secilenYerAdı destinationVC.secilenYerYorum = self.secilenYerYorum destinationVC.secilenYerLatitude = self.secilenYerLatitude destinationVC.secilenYerLongitude = self.secilenYerLongitude } } @IBAction func ekleButton(_ sender: Any) { //Ekleme yapacağımızı belirtiyoruz diğer sayfada if ile kontrol edeceğiz secilenYerAdı = "" performSegue(withIdentifier: "segue", sender: nil) } } |
Böylelikle uygulamalarımızda haritaları nasıl gösterebileceğimizi ve konumumuzu nasıl tespit edebileceğimizi öğrendik. Aynı zamanda kayıt ettiğimiz yerlere nasıl navigasyonla gidebileceğimizide öğrenmiş olduk. Bundan sonra sizde uygulamalarınızı bu özellikleri kullanarak zenginleştirebilirsiniz. Projenin kaynak kodlarını buraya tıklayarak indirebilirsiniz.