I have been trying desperately for the past few hours to make a phone call with swift when I call this function.
func callPhone(phoneNumber: String){
guard let url = URL(string:"telprompt:\(phoneNumber)") else {
print("failed to load url, phone number: \(phoneNumber)")
return
}
UIApplication.shared.open(url)
}
For some reason it doesn't work, I have researched online everywhere and still couldn't find a problem to why this wouldn't work. Some numbers would occasionally work, like if I tried "123456789" it would work. but if i try a different number it wouldn't work; The guard let statement doesn't work and the url would be empty.
Please help me. Any feedback would be very much appreciated.
Edit: So I found out when it is not working but I am not sure how to solve it. It doesn't work when I get the phone number from apple maps, but when I hard code the phone number it works.
Here is my full code:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
let regionMeters : Double = 10000
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
map.showsUserLocation = true
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionMeters, longitudinalMeters: regionMeters)
map.setRegion(region, animated: true)
}
searchLocations(search: "Restaurant")
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "Place"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
let btn = UIButton(type: .contactAdd)
annotationView!.rightCalloutAccessoryView = btn
} else {
annotationView!.annotation = annotation
}
return annotationView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let subtitle = view.annotation?.subtitle as! String
let splitted = subtitle.components(separatedBy: "+")
let number = splitted.last as! String
let trimmedNumber : String = number.components(separatedBy: [" ", "-", "(", ")"]).joined()
CallOnPhone(phoneNumber: trimmedNumber)
}
func searchLocations(search : String){
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = search
searchRequest.region = map.region
let activeSearch = MKLocalSearch(request: searchRequest)
activeSearch.start { (response, err) in
if response == nil {
print("no request")
} else {
for item in (response?.mapItems)!{
let annotation = MKPointAnnotation()
annotation.title = item.name
if let phone = item.phoneNumber {
annotation.subtitle = "Phone Number: \(phone as String)"
}
annotation.coordinate = item.placemark.coordinate
self.map.addAnnotation(annotation)
}
}
}
}
#objc func CallOnPhone(phoneNumber: String){
let newStringPhone = phoneNumber.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
print(newStringPhone)
if newStringPhone != ""{
if let url = URL(string: "tel://\(newStringPhone)"), UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
}
}
}
}
Thanks,
Try trimming the phone number.
let myphone:String = phoneNumber.trimmingCharacters(in:.whitespacesAndNewlines)
Full code:
if let url = URL(string: "tel://\(myphone)"),UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url, options: [:], completionHandler:nil)
} else {
UIApplication.shared.openURL(url)
}
} else {
Util.shared.showToast(message: "Can't make call from this device", view: self.view)
}
Below code show calling a number on button click. Also removing space if phonenum has spaces.
var phoneNumber = "Phone Number: 1234567"
var finalNumber = ""
let number = phoneNumber.split(separator: ":")
let tempNum = "\(number.last ?? "")"
print(tempNum)
let trimmedNumber : String = tempNum.components(separatedBy: [" ", "-", "(", ")"]).joined()
print(trimmedNumber)
finalNumber = trimmedNumber
print(finalNumber)
btn_Call.addTarget(self, action: #selector(CallOnPhone), for: .touchUpInside)
#objc func CallOnPhone(sender:UIButton){
let newStringPhone = finalNumber.replacingOccurrences(of: " ", with: "", options: .literal, range: nil)
print(newStringPhone)
if newStringPhone != ""{
if let url = URL(string: "tel://\(newStringPhone)"), UIApplication.shared.canOpenURL(url) {
if #available(iOS 10, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
}
}
}
Related
if (stringToURL?.isValidURL)! <-- Not sure why the complier requires optional chaining on stringToURL when it is safely declared in Guard statement. Also, string extension for isValidURL: Bool always returns Bool but compiler still wants unwrapping.
In this example, annotation.subtitle should already be string in URL format but I wanted to confirm.
Trying to use variables defined in guard becomes more convoluted than expected because further unwrapping is needed. Now I feel that I'm making a few lines of code overly complicated to follow/read with my implementations.
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let backupURL = URL(string: "https://www.google.com")!
guard let currentAnnotation = view.annotation, var stringToURL = currentAnnotation.subtitle else {
// currentAnnotation has blank subtitle. Handle by opening up any website.
UIApplication.shared.open(backupURL, options: [:])
return
}
if (stringToURL?.isValidURL)!{
stringToURL = stringToURL?.prependHTTPifNeeded()
if let url = URL(string: stringToURL!){
UIApplication.shared.open(url, options: [:])
} else {
UIApplication.shared.open(backupURL, options: [:])
}
}
}
extension String {
var isValidURL: Bool {
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
if let match = detector.firstMatch(in: self, options: [], range: NSRange(location: 0, length: self.endIndex.encodedOffset)) {
// it is a link, if the match covers the whole string
return match.range.length == self.endIndex.encodedOffset
} else {
return false
}
}
func prependHTTPifNeeded()-> String{
let first4 = self.prefix(4)
if first4 != "http" {
return "http://" + self
} else {
return self
}
}
}
The code block executes properly.
annotation.subtitle = "https://www.yahoo.com" <--- yahoo opens
annotation.subtitle = "www.yahoo.com" <--- yahoo opens
annotation.subtitle = "yahoo" <--- google.com opens because we did not have a valid URL string
The problem is that currentAnnotation.subtitle is a String??, because subtitle is not only a String?, itself, but it is also an optional property of MKAnnotation protocol. So a simple unwrap only verifies that the optional protocol subtitle was implemented, but not that the resulting String? was not nil. You have to unwrap that, too.
But you can do guard var stringToURL = view.annotation?.subtitle as? String else { ... }, and it will be properly unwrapped to a String:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let backupURL = URL(string: "https://www.google.com”)!
guard var stringToURL = view.annotation?.subtitle as? String else {
UIApplication.shared.open(backupURL)
return
}
if stringToURL.isValidURL {
stringToURL = stringToURL.prependHTTPifNeeded()
let url = URL(string: stringToURL) ?? backupURL
UIApplication.shared.open(url)
}
}
Note, that will open the backupURL if no string is provided, but if a string was provided and wasn’t a valid URL, it won’t do anything. So perhaps you meant the following, which will open backupURL if it can’t open stringToURL:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let backupURL = URL(string: "https://www.google.com")!
guard var stringToURL = view.annotation?.subtitle as? String,
stringToURL.isValidURL else {
UIApplication.shared.open(backupURL)
return
}
stringToURL = stringToURL.prependHTTPifNeeded()
let url = URL(string: stringToURL) ?? backupURL
UIApplication.shared.open(url)
}
Where:
extension String {
var isValidURL: Bool {
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let range = NSRange(startIndex..., in: self)
return detector.firstMatch(in: self, range: range)?.range == range
}
func prependHTTPifNeeded() -> String{
if prefix(4) != "http" {
return "http://" + self
} else {
return self
}
}
}
I am trying to create a seat map layout functionality that takes the coordinates and create a map i want to provide the value of the sections that the map contains. I am using custom collectionViewLayout to create the cells but i am getting that error in the title .
Here is my protocol-
protocol SeatMapDelegate: class {
func getSectionCoordinates() -> [Int]
}
Definition -
func getSectionCoordinates() -> [Int] {
return sectionHeader
}
and then i am assigning the values to the array
var sectionHeader = [Int]()
sectionHeader=(delegate?.getSectionCoordinates())!
below code is my project for search and find coordinate on the map:
Maybe help you
// ViewController.swift
// MapKit Starter
//
// Created by Ehsan Amiri on 10/25/16.
// Copyright © 2016 Ehsan Amiri. All rights reserved.
//
import UIKit
import MapKit
import Foundation
class ViewController: UIViewController {
#IBOutlet var mapView: MKMapView?
#IBOutlet weak var text: UITextField!
var index = 0
var indexx = 0
let locationManager = CLLocationManager()
var picName:String?
var place :MKAnnotation?
var places = [Place]()
var place1 :MKAnnotation?
var places1 = [Place]()
override func viewDidLoad() {
super.viewDidLoad()
//downpic()
self.requestLocationAccess()
}
override func viewWillAppear(_ animated: Bool) {
let defaults = UserDefaults.standard
let age = defaults.integer(forKey: "maptype")
switch (age) {
case 0:
mapView?.mapType = .standard
case 1:
mapView?.mapType = .satellite
case 2:
mapView?.mapType = .hybrid
default:
mapView?.mapType = .standard
}
}
#IBAction func info(_ sender: Any) {
}
override var prefersStatusBarHidden: Bool {
return true
}
func requestLocationAccess() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedAlways, .authorizedWhenInUse:
return
case .denied, .restricted:
print("location access denied")
default:
locationManager.requestWhenInUseAuthorization()
}
}
#IBAction func textField(_ sender: Any) {
mapView?.removeOverlays((mapView?.overlays)!)
mapView?.removeAnnotations((mapView?.annotations)!)
self.server()
_ = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(self.server), userInfo: nil, repeats: true)
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
if self.indexx != 0 {
self.addAnnotations()
self.addPolyline()
}
}
}
#objc func server() {
place = nil
places = [Place]()
place1 = nil
places1 = [Place]()
indexx = 0
let id = text.text
print("id=\(id!)")
let url = URL(string: "my server")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=\(id!)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
let stringgg = "notFound\n\n\n\n"
if responseString == stringgg {
print(stringgg)
}else{
let json = try! JSONSerialization.jsonObject(with: data, options: [])
let betterJSON = json as! NSArray
let jsonCount = betterJSON.count
print(betterJSON)
for item in betterJSON {
self.indexx += 1
let dictionary = item as? [String : Any]
let title = dictionary?["title"] as? String
let subtitle = dictionary?["description"] as? String
let latitude = dictionary?["latitude"] as? Double ?? 0, longitude = dictionary?["longitude"] as? Double ?? 0
self.place = Place(title: title, subtitle: subtitle, coordinate: CLLocationCoordinate2DMake(latitude , longitude ))
self.places.append(self.place as! Place)
print("latttt",longitude)
if self.indexx == 1{
let shipid = UserDefaults.standard
shipid.set(title, forKey: "origin")
shipid.set(subtitle, forKey: "date")
}
if jsonCount == self.indexx{
let shipid = UserDefaults.standard
shipid.set(title, forKey: "location")
self.place1 = Place(title: title, subtitle: subtitle, coordinate: CLLocationCoordinate2DMake(latitude , longitude ))
self.places1.append(self.place1 as! Place)
}
}
}
}
task.resume()
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
if self.indexx != 0 {
self.addAnnotations()
self.addPolyline()
}
}
}
func addAnnotations() {
print("hhhh",places)
mapView?.delegate = self
mapView?.removeAnnotations((mapView?.annotations)!)
mapView?.addAnnotations(places1)
let overlays = places1.map { MKCircle(center: $0.coordinate, radius: 100) }
mapView?.addOverlays(overlays)
}
func addPolyline() {
var locations = places.map { $0.coordinate }
let polyline = MKPolyline(coordinates: &locations, count: locations.count)
// print("Number of locations: \(locations.count)")
index = locations.capacity
mapView?.add(polyline)
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
else {
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "annotationView") ?? MKAnnotationView()
annotationView.image = UIImage(named:"place icon")
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.canShowCallout = true
return annotationView
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKCircle {
let renderer = MKCircleRenderer(overlay: overlay)
renderer.fillColor = UIColor.black.withAlphaComponent(0.5)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 2
return renderer
} else if overlay is MKPolyline {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.orange
renderer.lineWidth = 2
return renderer
}
return MKOverlayRenderer()
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//guard let annotation = view.annotation as? Place, let title = annotation.title else { return }
let shipidname = text.text
let shipid = UserDefaults.standard
shipid.set(shipidname, forKey: "shipid")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "shipinfo")
self.present(secondViewController, animated: true, completion: nil)
}
}
so I want to set up a map with navigation from the users location to a annotation that the user selected. I Have all the annotations loaded from a .Plist . someone help me out I'm just a beginner. this is my code for the map:
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate, UISearchBarDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBAction func searchButton(_ sender: Any) {
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
present(searchController, animated: true, completion: nil)
}
let locationManager = CLLocationManager()
// Vraag om locatie van gebruiker
func requestLocationAccess()
{
let status = CLLocationManager.authorizationStatus()
switch status
{
case .authorizedAlways, .authorizedWhenInUse:
return
case .denied, .restricted:
print("location access denied")
default:
locationManager.requestWhenInUseAuthorization()
}
}
class func createViewAnnotationForMap(mapView:MKMapView, annotation:MKAnnotation)->MKAnnotationView
{
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "PinAnnotation"){
return annotationView
}
else
{
let returnedAnnotationView:MKPinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier:"PinAnnotation")
returnedAnnotationView.animatesDrop = false
returnedAnnotationView.canShowCallout = true
return returnedAnnotationView
}
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
{
//Ignoring user
UIApplication.shared.beginIgnoringInteractionEvents()
//Activity Indicator
let activityIndicator = UIActivityIndicatorView()
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.startAnimating()
self.view.addSubview(activityIndicator)
//Hide search bar
searchBar.resignFirstResponder()
dismiss(animated: true, completion: nil)
//Create the search request
let searchRequest = MKLocalSearchRequest()
searchRequest.naturalLanguageQuery = searchBar.text
let activeSearch = MKLocalSearch(request: searchRequest)
activeSearch.start { (response, error) in
activityIndicator.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
if response == nil
{
print("ERROR")
}
else
{
//Getting data
let latitude = response?.boundingRegion.center.latitude
let longitude = response?.boundingRegion.center.longitude
//Create annotation
let annotation = MKPointAnnotation()
annotation.title = searchBar.text
annotation.coordinate = CLLocationCoordinate2DMake(latitude!, longitude!)
self.mapView.addAnnotation(annotation)
//Zooming in on annotation
let coordinate:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude!, longitude!)
let span = MKCoordinateSpanMake(0.1, 0.1)
let region = MKCoordinateRegionMake(coordinate, span)
self.mapView.setRegion(region, animated: true)
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue
return renderer
}
override func viewDidLoad()
{
super.viewDidLoad()
requestLocationAccess()
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
mapView.showsScale = true
mapView.isRotateEnabled = true
mapView.showsUserLocation = true
mapView.showsCompass = true
mapView.delegate = self
//Regio instellen
var newRegion:MKCoordinateRegion = MKCoordinateRegion()
newRegion.center.latitude = -25.106303;
newRegion.center.longitude = 133.587542;
newRegion.span.latitudeDelta = 22;
newRegion.span.longitudeDelta = 22;
self.mapView.setRegion(newRegion, animated: true)
if let cityDetailsPath = Bundle.main.path(forResource: "places", ofType: "plist") {
guard let cityDetails = NSArray(contentsOfFile: cityDetailsPath) as? [[String: String]] else {return}
for city in cityDetails
{
guard let latStr = city["latitude"] else { continue }
guard let lonStr = city["longitude"] else { continue }
guard let titleStr = city["title"] else { continue }
guard let subtitleStr = city["subTitle"] else { continue }
if let lat = Double(latStr) {
if let lon = Double(lonStr) {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2DMake(lat,lon)
annotation.title = titleStr
annotation.subtitle = subtitleStr
mapView.addAnnotation(annotation)
}
}
}
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
}
extension MapViewController: MKMapViewDelegate {
func createViewAnnotationForMap(mapView:MKMapView, annotation:MKAnnotation)->MKAnnotationView {
let annoannotationId = "PinAnnotation"
if let annotationView = self.mapView.dequeueReusableAnnotationView(withIdentifier: annoannotationId) {
return annotationView
}
else
{
let returnedAnnotationView:MKPinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annoannotationId)
returnedAnnotationView.animatesDrop = false
returnedAnnotationView.canShowCallout = true
return returnedAnnotationView
}
}
}
Use didSelect delegate method.
e.g.
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
guard let annotation = view.annotation else {
return
}
let directionRequest = MKDirectionsRequest()
directionRequest.source = MKMapItem.forCurrentLocation()
directionRequest.destination = MKMapItem(placemark: MKPlacemark(coordinate: annotation.coordinate))
directionRequest.transportType = .automobile
let directions = MKDirections(request: directionRequest)
directions.calculate {
(response, error) -> Void in
guard let response = response else {
if let error = error {
print("Error: \(error)")
}
return
}
if !response.routes.isEmpty {
let route = response.routes[0]
DispatchQueue.main.async { [weak self] in
self?.mapView.add(route.polyline)
}
}
}
}
Don't forget guard to prevent crash.
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) ->
MKOverlayRenderer {
guard overlay is MKPolyline else {
return MKPolylineRenderer()
}
...
}
Can't display color of annotation point in map , how it could be solved here's my code .i declared even function of color in MKPointAnnotation even i can't change the color , is there i have missed any codes ??
class NearbyViewController: UIViewController,MKMapViewDelegate,CLLocationManagerDelegate {
#IBOutlet weak var mapview: MKMapView!
#IBOutlet weak var name: UILabel!
var locationManager : CLLocationManager!
#IBOutlet weak var menu: UIBarButtonItem!
var schoolMap : [schools] = []
var collegeMap : [Colleges] = []
var universityMap : [University] = []
class MyPointAnnotation : MKPointAnnotation {
var pinTintColor: UIColor?
}
override func viewDidLoad() {
super.viewDidLoad()
getschoolMapJson()
getcollegeMapJson()
getuniversityMapJson()
menu.target = self.revealViewController()
menu.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.distanceFilter = 1.00
locationManager.startUpdatingLocation()
}
override func viewWillAppear(_ animated: Bool) {
mapview.reloadInputViews()
}
override func viewDidAppear(_ animated: Bool) {
mapview.reloadInputViews()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations[0]
let span = MKCoordinateSpanMake(0.05, 0.05)
let mylocation = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region = MKCoordinateRegionMake(mylocation, span)
mapview.setRegion(region, animated: true)
self.mapview.showsUserLocation = true
}
func getschoolMapJson(){
if (schoolMap.count > 0){
return
}
let url = NSURL(string: "http://www.myeducationhunt.com/api/v1/schools")
var request = URLRequest(url: url! as URL)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(request).responseJSON(){ response in
switch response.result{
case.success(let data):
print("success api",data)
let myresponse = JSON(data)
/*for i in 0..<self.myresponse.count{
let schools_data = schools(schoolJson:self.myresponse[i])
self.schooldata.append(schools_data)
}*/
for school in myresponse.array!{
let schoolsObj = schools(schoolJson: school)
//Add Pin
let location = CLLocationCoordinate2DMake((schoolsObj.latitude) , (schoolsObj.longitude))
let span = MKCoordinateSpanMake(10.0, 10.0)
let region = MKCoordinateRegionMake(location, span)
self.mapview.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = schoolsObj.name
let pincolor = MyPointAnnotation()
pincolor.pinTintColor = .blue
// MKPinAnnotationColor.green
// let pinC = MKPinAnnotationView.greenPinColor()
// self.mapview.addAnnotation(pinC as! MKAnnotation)
self.mapview.addAnnotation(annotation)
self.schoolMap.append(schoolsObj)
}
// self.mapview.reloadInputViews()
case.failure(let error):
print("Not Success",error)
}
}
}
func getcollegeMapJson(){
if (collegeMap.count > 0){
return
}
let url = NSURL(string: "http://www.myeducationhunt.com/api/v1/colleges")
var request = URLRequest(url: url! as URL)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(request).responseJSON(){ response in
switch response.result{
case.success(let data):
print("success api",data)
let myresponse = JSON(data)
/*for i in 0..<self.myresponse.count{
let schools_data = schools(schoolJson:self.myresponse[i])
self.schooldata.append(schools_data)
}*/
for college in myresponse.array!{
let collegeObj = Colleges(collegeJson: college)
//Add Pin
let location = CLLocationCoordinate2DMake((collegeObj.latitude) , (collegeObj.longitude))
let span = MKCoordinateSpanMake(10.0, 10.0)
let region = MKCoordinateRegionMake(location, span)
self.mapview.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = collegeObj.name
self.mapview.addAnnotation(annotation)
self.collegeMap.append(collegeObj)
}
case.failure(let error):
print("Not Success",error)
}
}
}
func getuniversityMapJson(){
if (universityMap.count > 0){
return
}
let url = NSURL(string: "http://www.myeducationhunt.com/api/v1/universities")
var request = URLRequest(url: url! as URL)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
Alamofire.request(request).responseJSON(){ response in
switch response.result{
case.success(let data):
print("success api",data)
let myresponse = JSON(data)
for university in myresponse.array!{
let universityObj = University(universityJson: university)
//Add Pin
let location = CLLocationCoordinate2DMake((universityObj.latitude) , (universityObj.longitude))
let span = MKCoordinateSpanMake(10.0, 10.0)
let region = MKCoordinateRegionMake(location, span)
self.mapview.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = universityObj.name
self.mapview.addAnnotation(annotation)
self.universityMap.append(universityObj)
}
case.failure(let error):
print("Not Success",error)
}
}
}
}
I am confused to display annotation point color i tried in many ways
but can't do it .
You have to add the following function. I hope this will solve your issue.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "myAnnotation") as? MKPinAnnotationView
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myAnnotation")
} else {
annotationView?.annotation = annotation
}
if let annotation = annotation as? MyPointAnnotation {
annotationView?.pinTintColor = annotation.pinTintColor
}
return annotationView
}
I do have the problem that I do not know how to specify which UIButton .DetailDisclosure type is pressed. I do have multiple Annotations and I want to show the details of this specific Annotation. I hope that question is clear and someone can help me.
Thank you in advance.
This is my code right now
import UIKit
import MapKit
import CoreLocation
class FirstViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
var myURL = NSURL(string: "http://www...");
var Daten = NSMutableArray()
var Test = ""
#IBOutlet weak var Mapkit: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
let request = NSMutableURLRequest(URL: myURL!)
request.addValue("application/json", forHTTPHeaderField: "Accept")
_ = NSURLSession.sharedSession().downloadTaskWithRequest(request)
let Session = NSURLSession.sharedSession()
Session.dataTaskWithRequest(request)
do {
let data = NSData(contentsOfURL: myURL!)
_ = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
self.Daten = try (NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSDictionary)["Ort"] as! NSMutableArray
for parseJSON in self.Daten{
let resultName:String = parseJSON["Name"] as! String!;
let länge:String = parseJSON["breite"] as! String!;
let breite:String = parseJSON["laenge"] as! String!;
self.Test = resultName
}
for Pin in self.Daten{
let Name = Pin["Name"] as! String!
let longitude = Pin["laenge"] as! String!
let breite = Pin["breite"] as! String!
let longitudeDouble = Double(longitude!)
let breitedouble = Double(breite!)
let Location = MKPointAnnotation()
let Coordinat = CLLocationCoordinate2DMake(longitudeDouble!, breitedouble!)
Location.coordinate = Coordinat
Location.title = Name
self.Mapkit.addAnnotation(Location)
}
}
catch {
print(error)
}
// more here
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var anView:MKAnnotationView = MKAnnotationView()
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation is MKUserLocation) {
//if annotation is not an MKPointAnnotation (eg. MKUserLocation),
//return nil so map draws default view for it (eg. blue dot)...
return nil
}
let reuseId = "test"
if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:reuseId)
annotationView.enabled = true
annotationView.canShowCallout = true
let btn = UIButton(type: .DetailDisclosure)
annotationView.rightCalloutAccessoryView = btn
return annotationView
}
}
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//I don't know how to convert this if condition to swift 1.2 but you can remove it since you don't have any other button in the annotation view
if (control as? UIButton)?.buttonType == UIButtonType.DetailDisclosure {
mapView.deselectAnnotation(view.annotation, animated: false)
performSegueWithIdentifier("Infos", sender: view)
}
}
}
The MKAnnotation is passed to you in func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl). You can use it to search for the right action in a hash map.
Or even simpler, test for equality if only one annotation is different.