Swift Mapkit Received memory warning - ios

Im developing ipad app and looking memory using good all viewcontrollers but my MapDetailViewController gives me Received memory warning how can i resolve it .
All viewcontrollers use my app max 34.MB memory but MapDetailViewController using 100 MB More. My codes under below what is wrong ?
import UIKit
import MapKit
class MapDetailViewController: UIViewController,MKMapViewDelegate {
#IBOutlet var mapView:MKMapView!
#IBOutlet weak var mapArea: DesignableView!
#IBOutlet weak var nameSales: DesignableLabel!
var showmapListcomming = String()
override func viewDidLoad() {
super.viewDidLoad()
// Show Map
let myString: String = showmapListcomming
var myStringArr = myString.componentsSeparatedByString(",")
nameSales.text = myStringArr[0]
let annotation = MKPointAnnotation()
let latitude:CLLocationDegrees = (myStringArr[1] as NSString).doubleValue
let longitude:CLLocationDegrees = (myStringArr[2] as NSString).doubleValue
let latDelta:CLLocationDegrees = 150
let lonDelta:CLLocationDegrees = 150
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: false)
annotation.coordinate = location
annotation.title = myStringArr[0]
annotation.subtitle = "User"
mapView.addAnnotation(annotation)
}
// MARK: - MKMapViewDelegate methods
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView()
return annotationView
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Related

IOS Map Pins are not Showing?

I am struggling with my iOS code. The overall goal of the project is to show the pins on the map, I've tried multiple ways to make the pins appear on the map such as the below, I am not sure what I am doing wrong. The code runs fine, the pins are not appearing. I've made changes to my functions but seem to get the same error. Any insight on what I may be missing?
"import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
#IBOutlet weak var logout: UIBarButtonItem!
#IBOutlet weak var refresh: UIBarButtonItem!
#IBOutlet weak var pinDrop: UIBarButtonItem!
var studentLocation = [StudentInformation]()
var annotations = [MKPointAnnotation]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear (_ animated: Bool) {
super.viewDidAppear(true)
getStudentPins()
}
#IBAction func refresh(_ sender: UIBarButtonItem) {
getStudentPins ()
}
#IBAction func logout(_ sender: UIBarButtonItem) {
self.activityIndicator.startAnimating()
UdacityClient.logout {
DispatchQueue.main.async {
self.dismiss(animated: true, completion: nil)
self.activityIndicator.stopAnimating()
}
}
}
#IBAction func addLocation(_ sender: Any) {
performSegue(withIdentifier: "addLocation", sender: nil)
}
func getStudentPins () {
self.activityIndicator.startAnimating()
UdacityClient.getStudentLocations() { locations, error in
self.mapView.removeAnnotations(self.annotations)
self.annotations.removeAll()
self.studentLocation = locations ?? []
for dictionary in locations ?? [] {
let latitude = CLLocationDegrees(dictionary.latitude ?? 0.0)
let longitude = CLLocationDegrees(dictionary.longitude ?? 0.0)
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let firstName = dictionary.firstName
let lastName = dictionary.lastName
let mediaURL = dictionary.mediaURL
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = "\(firstName) \(lastName)"
annotation.subtitle = mediaURL
self.annotations.append(annotation)
}
DispatchQueue.main.async {
self.mapView.addAnnotations(self.annotations)
self.activityIndicator.stopAnimating()
}
}
}
private func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotation? {
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.pinTintColor = .green
pinView!.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
}
else {
pinView!.annotation = annotation
}
return pinView?.annotation
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
if let toOpen = view.annotation?.subtitle {
openLink(toOpen ?? "")
}
}
}
}"
They're called annotations in the MapKit and you should instantiate them like so:
let annotation = MKPointAnnotation()
then in the viewDidLoad() method just set the coordinates and add them to the map like:
annotation.coordinate = CLLocationCoordinate2D(latitude: 11.12, longitude: 12.11)
mapView.addAnnotation(annotation)
The numbers are your coordinates. Try by adding sample coordinates on the map first and then add all coordinates which you are getting from the client.
you can also add more information using:
annotation.title = "Your text here"
//You can also add a subtitle that displays under the annotation such as
annotation.subtitle = "One day I'll go here..."

My annonation isn't visible when I add it in the viewDidLoad of my app

I am developing an app where the user has to mark a location on a map, and then save it. My app then archives it, and when the user wants to see that location, the app is supposed to retreive the location's coordinates, and add an annonation on the map if the coordinates exist. Here is the piece of code I created to display the information the user selected-
#IBOutlet var mapGestureRecognizer: UIGestureRecognizer!
var item: itemData?
// Item Outlets
#IBOutlet weak var itemInfoView: UIView!
#IBOutlet weak var itemNameTextField: UITextField!
#IBOutlet weak var itemDescriptionLabel: UITextView!
#IBOutlet weak var mapView: MKMapView!
// Item Location Outlets
#IBOutlet weak var itemLocationView: UIView!
#IBOutlet weak var itemLocationTextView: UITextView!
let dropPin = MKPointAnnotation()
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.delegate = self
// Data loading
itemNameTextField.delegate = self
itemDescriptionLabel.delegate = self
itemLocationTextView.delegate = self
// Press recognizer
func mapViewFunc(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "myAnnotationView")
// configure the view
return annotationView
}
if let item = item {
itemNameTextField.text = item.itemName
itemDescriptionLabel.text = item.itemDescription
itemLocationTextView.text = item.itemPlace
dropPin.coordinate = mapView.convert(item.mapPoint, toCoordinateFrom: mapView)
dropPin.title = "Location of \(item.itemName)"
mapView.addAnnotation(dropPin)
print("Set the location of item pin to \(String(describing: dropPin.coordinate))")
}
// Styles
itemInfoView.layer.cornerRadius = 3
itemInfoView.layer.shadowColor = UIColor(red:0/255.0, green:0/255.0, blue:0/255.0, alpha: 1.0).cgColor
itemInfoView.layer.shadowOffset = CGSize(width: 0, height: 1.75)
itemInfoView.layer.shadowRadius = 1.7
itemInfoView.layer.shadowOpacity = 0.45
itemLocationView.layer.cornerRadius = 3
itemLocationView.layer.shadowColor = UIColor(red:0/255.0, green:0/255.0, blue:0/255.0, alpha: 1.0).cgColor
itemLocationView.layer.shadowOffset = CGSize(width: 0, height: 1.75)
itemLocationView.layer.shadowRadius = 1.7
itemLocationView.layer.shadowOpacity = 0.45
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
let annotation = MKPointAnnotation()
//let point = mapView.convert(coordinate, toPointTo: overlayView)
func action(gestureRecognizer:UIGestureRecognizer){
if let item = item {
dropPin.coordinate = mapView.convert((item.mapPoint), toCoordinateFrom: mapView)
dropPin.title = "Location of \(item.itemName)"
mapView.addAnnotation(dropPin)
print("Set the location of item pin to \(String(describing: dropPin.coordinate))")
}
else {
let itemName = itemNameTextField.text
let touchPoint = gestureRecognizer.location(in: mapView)
let newCoordinates = mapView.convert(touchPoint, toCoordinateFrom: mapView)
annotation.coordinate = newCoordinates
annotation.title = "Location of \(itemName!)"
mapView.addAnnotation(annotation)
}
}
#IBAction func mapLocationPress(_ sender: UILongPressGestureRecognizer) {
action(gestureRecognizer: mapGestureRecognizer)
}
All the print statements I've created work, so I know that the app does save the coordinates, and that it does convert them properly. However, when the app loads the information in the if let item = item portion of the viewDidLoad, the pin isn't dropped onto the map like it's supposed to.
Does anybody see why my code isn't working the way it's supposed to? Thanks!
If you need my full code, tell me, and I will put it into my question.
You need to use
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "myAnnotationView")
// configure the view
return annotationView
}
outside your viewDidLoad() function
You should put mapViewFunc out of viewDidLoad, but if you want to leave it in viewDidLoad
try
func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
// add pin
}
}

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) error occurs when getting the latitude and longitude

Please help me with this problem
import Foundation
import UIKit
import MapKit
class DetailViewController : UIViewController {
#IBOutlet weak var mapView: MKMapView!
var selectedLocation : LocationModel?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
// Create coordinates from location lat/long
var poiCoodinates: CLLocationCoordinate2D = CLLocationCoordinate2D()
poiCoodinates.latitude = CDouble(self.selectedLocation!.latitude!)! //Problem is in this line
poiCoodinates.longitude = CDouble(self.selectedLocation!.longitude!)!
// Zoom to region
let viewRegion: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(poiCoodinates, 750, 750)
self.mapView.setRegion(viewRegion, animated: true)
// Plot pin
let pin: MKPointAnnotation = MKPointAnnotation()
pin.coordinate = poiCoodinates
self.mapView.addAnnotation(pin)
//add title to the pin
pin.title = selectedLocation!.name
}
}
You have not initialised var selectedLocation : LocationModel? so when you ask for self.selectedLocation! it crash.
Add that needed initialisation and try to refactor your code in this
way:
override func viewDidAppear(animated: Bool) {
guard let location = self.selectedLocation, let latitude = location.latitude, let longitude = location.longitude else {
return //Here was an error, so you can not continue, report it or do something about it before returning
}
// Create coordinates from location lat/long
var poiCoodinates: CLLocationCoordinate2D = CLLocationCoordinate2D()
poiCoodinates.latitude = CDouble(latitude)!
poiCoodinates.longitude = CDouble(longitude)!
// Zoom to region
let viewRegion: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(poiCoodinates, 750, 750)
self.mapView.setRegion(viewRegion, animated: true)
// Plot pin
let pin: MKPointAnnotation = MKPointAnnotation()
pin.coordinate = poiCoodinates
self.mapView.addAnnotation(pin)
//add title to the pin
pin.title = location.name
}
I finally found the solution and here it goes:
import MapKit
class DetailViewController : UIViewController, MKMapViewDelegate {
//var mapType:UISegmentedControl!
//var showPointsOfInterest:UISwitch!
#IBOutlet weak var mapView: MKMapView!
#IBAction func showDirection(sender: AnyObject) {
}
var selectedLocation : LocationModel?
let locationManager = CLLocationManager()
var currentPlacemark:CLPlacemark?
//var segmentedControlAciton:UISegmentedControl!
#IBAction func myLocation(sender: AnyObject) {
// Request for a user's authorization for location services
locationManager.requestWhenInUseAuthorization()
let status = CLLocationManager.authorizationStatus()
if status == CLAuthorizationStatus.AuthorizedWhenInUse {
mapView.showsUserLocation = true
}
}
//
override func viewDidLoad() {
super.viewDidLoad()
// mapView.showsUserLocation = true
title = selectedLocation?.name
mapView.delegate = self
}
override func viewDidAppear(animated: Bool) {
// Create coordinates from location lat/long
var poiCoordinates: CLLocationCoordinate2D = CLLocationCoordinate2D()
poiCoordinates.latitude = CDouble(self.selectedLocation!.latitude!)!
poiCoordinates.longitude = CDouble(self.selectedLocation!.longitude!)!
// Zoom to region
let viewRegion: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(poiCoordinates, 750, 750)
self.mapView.setRegion(viewRegion, animated: true)
// Plot pin
let pin: MKPointAnnotation = MKPointAnnotation()
pin.coordinate = poiCoordinates
self.mapView.addAnnotation(pin)
//add title to the pin
pin.title = selectedLocation!.name
pin.subtitle=selectedLocation!.address
mapView.showsScale = true
}

Change color pin iOS 9 Mapkit

I don't know how to change the code for the pin color in iOS 9 (because lately Apple changed the code for it), and I'm still new in Swift. So, I don't know how to integrate pinTintColor in my code now.
Please find below my code:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let annotation = MKPointAnnotation()
let latitude:CLLocationDegrees = 40.5
let longitude:CLLocationDegrees = -74.6
let latDelta:CLLocationDegrees = 150
let lonDelta:CLLocationDegrees = 150
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
map.setRegion(region, animated: false)
annotation.coordinate = location
annotation.title = "Niagara Falls"
annotation.subtitle = "One day bla bla"
map.addAnnotation(annotation)
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
// simple and inefficient example
let annotationView = MKPinAnnotationView()
annotationView.pinColor = .Purple
return annotationView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
pinColor is deprecated in iOS 9, use pinTintColor instead.
Example:
let annotationView = MKPinAnnotationView()
annotationView.pinTintColor = UIColor.purpleColor()
Although the OP specifically asks for iOS 9, the following could ensure that the "non-deprecated" method prior to iOS 9 could be called:
if #available(iOS 9, *) {
annotationView.pinTintColor = UIColor.purpleColor()
} else {
annotationView.pinColor = .Purple
}
If your minimal target is iOS 9 as you specifically ask here, the above would then be redundant - Xcode would let you know that with a warning, as well, for your information.

No Labels being displayed in MapKit

Could someone let me know why my labels are not being displayed. I am running a loop thru an array with coordinates in it. Its displaying my 3 pins with 1 being green, two blue which is what i want but my labels are not being displayed, any ideas?
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var maps: MKMapView!
var locationManager = CLLocationManager()
var flag = true
override func viewDidLoad() {
super.viewDidLoad()
let CoordinatesArray = ["blah,-blah, 11:45","blah, -blah,00:00", "blah,-blah, 12:45"];
self.maps.delegate = self
sendPoints(CoordinatesArray);
}
func sendPoints(array:[String]){
let latDelta:CLLocationDegrees = 0.015 //difference of lats from one side of screen to another
let longDelta:CLLocationDegrees = 0.015 //difference of lats from one side of screen to another
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
for (var i=0;i<array.count;i++){
var separateComma = array[i].componentsSeparatedByString(",")
var location:CLLocationCoordinate2D
if(flag){
location = CLLocationCoordinate2DMake(separateComma[0].doubleValue,separateComma[1].doubleValue)
let length:CLLocationDistance = 200
let cir:MKCircle = MKCircle(centerCoordinate: location, radius: length)
maps.addOverlay(cir)
}else{
location = CLLocationCoordinate2DMake(separateComma[0].doubleValue,separateComma[1].doubleValue)
}
let point = MKPointAnnotation()
point.title = "Home"
point.subtitle = "time for home"
point.coordinate = location
maps.addAnnotation(point)
maps.selectAnnotation(point, animated: true)
maps.setRegion(MKCoordinateRegionMake(point.coordinate, MKCoordinateSpanMake(latDelta,longDelta)), animated: true)
}
}
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let overlayRenderer : MKCircleRenderer = MKCircleRenderer(overlay: overlay);
overlayRenderer.lineWidth = 150
overlayRenderer.fillColor = UIColor.blueColor()
overlayRenderer.alpha = 0.15
return overlayRenderer
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation.isKindOfClass(MKUserLocation)){
return nil
}
var myPin = mapView.dequeueReusableAnnotationViewWithIdentifier("MyIdentifier") as? MKPinAnnotationView
if myPin != nil {
return myPin
}
myPin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "MyIdentifier")
if(flag){
myPin?.pinTintColor = UIColor.greenColor()
}else{
myPin?.pinTintColor = UIColor.blueColor()
}
flag = false;
return myPin
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension String {
var doubleValue: Double {
return (self as NSString).doubleValue
}
}
You have to set canShowCallout property.
myPin = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "MyIdentifier")
myPin?.canShowCallout = true
In my case I was delegating the map before being called.
So... that'd be the mistake I was facing.
self.m_map = MKMapView()
self.m_map?.delegate = self
Hope it helps somebody :-)

Resources