How do I save annotations? - swift

I have my code so it puts an annotation on the map each time the user clicks a button, but when the user closes out of the app, the annotation disappears. How do I make it so the annotations stays on the map even when the user closes the app? Below is my code:
import UIKit
import CoreLocation
import MapKit
class UpdateCar: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var lblLocation: UILabel!
var locationManager = CLLocationManager()
var myPosition = CLLocationCoordinate2D()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
println("Updating Car Location \(newLocation.coordinate.latitude) , \(newLocation.coordinate.longitude) ")
myPosition = newLocation.coordinate
locationManager.stopUpdatingLocation()
lblLocation.text = "\(newLocation.coordinate.latitude) , \(newLocation.coordinate.longitude)"
}
#IBAction func findUserLocationAndDropPin(sender: UIButton) {
var userLocationCoordinates = CLLocationCoordinate2DMake(locationManager.location.coordinate.latitude, locationManager.location.coordinate.longitude)
var pinForUserLocation = MKPointAnnotation()
pinForUserLocation.coordinate = userLocationCoordinates
mapView.addAnnotation(pinForUserLocation)
mapView.showAnnotations([pinForUserLocation], animated: true)
}
}

You have to save it in a persistent store.
Few options:
CoreData, the native way of saving data, recommended, not too easy
NSUserDefaults, usually thought for small stuff, also native, not recommended, very easy though
Another API for managing a persistent store like Realm (similar to CoreData, a little easier but not native)

//when I need to save for example, the last date on which the user login my app will use the setObject function, this will save a value ("10/05/2015") in the "lastlogin" key
var lastLogin = "10/05/2015"
NSUserDefaults.standarUserDefaults().setObject(lastLogin, forkey: "lastLogin")
//And when I need to retrieve the stored value in the "lastlogin" key which I use is "objectForKey" function
NSUserDefaults.standarUserDefaults().objectForKey("lastLogin")
see following link:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html#//apple_ref/occ/instm/NSUserDefaults/setObject:forKey:

Related

Is there any way to customize the UNnotification for local notifications in swift

I am new to Xcode and swift. I want to know that is there any way that we can customize the local notifications. If possible I also want to add a map on the notification.
Thanks in advance
You can add a target from File -> New -> Target -> Notification Content Extension
which will add an extension for your custom UI. Set the UNNotificationExtensionCategory to the string identifier.
If you want to add a map on the notification , add a Mapkit View into storyboard in the extension. I have attached the code for the map:
import UIKit
import UserNotifications
import UserNotificationsUI
import MapKit
import CoreLocation
class NotificationViewController: UIViewController, UNNotificationContentExtension{
// #IBOutlet weak var mapView: MKMapView!
#IBOutlet var label: UILabel?
fileprivate let locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
// mapView.showsUserLocation = true
}
func didReceive(_ notification: UNNotification) {
//self.label?.text = notification.request.content.body
self.label?.text = "Reminder for your charging "
}
#IBAction func notibutton(_ sender: Any) {
}
}
Thanks for the help.
I tried using the notification extension identifier and called in the function in the app delegate of the main target
It worked for me also the map is displayed in the notification.

UILabel will not update to show fetched location coordinates

So I'm just trying to do a simple test in Xcode, where the app will fetch the user's current location and display the coordinates on screen. This can then be updated by pressing a 'Fetch Location' button.
The app doesn't seem to be fetching any coordinates (the UILabel only ever displays default text).
It's just a single-page app. And yes, the #IBOutlet and #IBAction are correctly linked.
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var labelLocation: UILabel!
var locationManager = CLLocationManager()
var myPosition = CLLocationCoordinate2D()
#IBAction func fetchLocation(_ sender: Any) {
locationManager.startUpdatingLocation()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
print("Got Location \(newLocation.coordinate.latitude), \(newLocation.coordinate.longitude)")
myPosition = newLocation.coordinate
locationManager.stopUpdatingLocation()
labelLocation.text = "Got Location \(newLocation.coordinate.latitude), \(newLocation.coordinate.longitude)"
}
}
Step 1:
Enable the Privacy - Location When In Use Usage Description in your info.plist file
Go to your info.plist file
Click on + on Information property list and type Privacy - Location When In Use Usage Description
In the value type why you want to request the users location (this will be shown to the user)
Step 2:
Get the location
Use this code:
guard let latitude = manager.location?.coordinate.latitude, let longitude = manager.location?.coordinate.longitude else { return }
locationManager.stopUpdatingLocation()
labelLocation.text = "Got Location \(latitude), \(longitude)"
Ok, I think that you can resolve it adding the "Privacy - Location When In Use Usage Description" key into Info.plist, this is an important step in Location topic.
Regards!

UISlider, save status

My question is about the UISlider. I managed to implement everything but i don't know how i can save its status.
Ive looked everywhere but al the posts are in older versions of swift/xcode. So the question is how do i save its status so that when i go to another view and then come back the status is still the same.
Thanks very much!
import UIKit
class SettingsViewController: UIViewController {
var sequeInt = 0
let savedWordLength = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var wordLength: UISlider!
#IBOutlet weak var wordLengthValue: UILabel!
var selectedValue: Int = 5
#IBAction func valueChanged(sender: UISlider) {
selectedValue = Int(sender.value)
savedWordLength.setInteger(selectedValue, forKey: "myInt")
let ourInt = savedWordLength.integerForKey("myInt")
sequeInt = ourInt
print (sequeInt)
wordLengthValue.text = String(ourInt)
}
UISlider value property is a Float so you can use NSUserDefault's method setFloat to save its value and retrieve it next time your view appears using NSUserDefaults method floatForKey.
to save it:
NSUserDefaults.standardUserDefaults().setFloat(sender.value, forKey: "wordLength")
load it:
override func viewWillAppear(animated: Bool) {
wordLength.setValue(NSUserDefaults.standardUserDefaults().floatForKey("wordLength"), animated: false)
}
Follow these steps.
In your view will appear.
fontSlider.setValue(UserDefaults.standard.float(forKey: "slider_value"), animated: false)
Take another outlet from storyBoard as "editingDidEnd".
In that function:
UserDefaults.standard.set(fontSlider.value, forKey: "slider_value")
And finally in your ValueChanged Outlet.
UserDefaults.standard.set(fontSlider.value, forKey: "slider_value")

How do I save a users location and display it on a map using a pin (or some other marker)?

What I want to do is have a button that the user can click that would save their current location. Then, on a map, a pin would appear where the save location is. How would I go about doing this? I've searched for some sample code but I can't find any that work or are in Swift.
I have it so the user can also see where they are at at all times. Bellow is what I currently have for code.
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
#IBOutlet var Map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
println("Updating Location \(newLocation.coordinate.latitude) , \(newLocation.coordinate.longitude) ")
let span = MKCoordinateSpanMake(0.0009, 0.0009)
let region = MKCoordinateRegion(center: newLocation.coordinate, span: span)
Map.setRegion(region, animated: false)
}
}
What would I add to this code to accomplish my goal that I described in my first paragraph?
Try like this:
Create your button action to findUserLocationAndDropPin():
Capture the userLocationCoordinates using
CLLocationCoordinate2DMake();
Create your pinForUserLocation using MKPointAnnotation();
Assign your pinForUserLocation.coordinate to be equal to
userLocationCoordinates;
Get your mapView and addAnnotation;
Finally ask mapView to showAnnotations.
This code is what I mean and should do that, at least until iOS 8.4 :
#IBAction func findUserLocationAndDropPin(sender: UIButton) {
var userLocationCoordinates = CLLocationCoordinate2DMake(locationManager.location.coordinate.latitude, locationManager.location.coordinate.longitude)
var pinForUserLocation = MKPointAnnotation()
pinForUserLocation.coordinate = userLocationCoordinates
mapView.addAnnotation(pinForUserLocation)
mapView.showAnnotations([pinForUserLocation], animated: true)
}
Good question!
Try adding an array that stores newLocation.coordinate when an IBAction takes place. Then, you can set a pin by using this sample code as an example:
override func viewDidLoad() {
super.viewDidLoad()
// Set map view delegate with controller
self.mapView.delegate = self
let newYorkLocation = CLLocationCoordinate2DMake(40.730872, -74.003066)
// Drop a pin
let dropPin = MKPointAnnotation()
dropPin.coordinate = newYorkLocation
dropPin.title = "New York City"
mapView.addAnnotation(dropPin)
}
But then just set dropPin.coordinate to be the value stored in the array.
Ok, so firstly you want to get permission from the user:
Add the CoreLocation framework
Update info.plist by adding NSLocationWhenInUseUsageDescription
Your code in viewDidLoad is correct
You can use the simpler method:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { }
Inside that, set:
var userLocation : CLLocation = locations[0] as! CLLocation
Now create a CLLocationCoordinate2D by using userLocation.latitude and .longitude
create an annotation with MKPointAnnotation(), and set annotation.coordinate to be the CLLocationCoordinate2D above.
set the .title if required
map.addAnnotation(annotation)
This will in effect add a pin every time the user's location is updated - so you might want to think about removing the previous pins. Also, it's not very effective if y you're getting updates every half second or so, so consider simply setting the mapView to show the region every time it is updated, rather than a pin.
Hope this helps!

Core Location in Swift

This is sample code. NSLocationAlwaysUsageDescription key in Info.plist installed. All work fine - program receives the coordinates.... displays them.....
And it continues to update them permanently! In the case of the iOS simulator - it is not critical, but in the case of a real application it is very quickly drain the battery. How to make an application launched Core Location, received location, and got shut down Core Location?
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet var locLabel: UILabel
#IBOutlet var latLabel: UILabel
#IBOutlet var lonLabel: UILabel
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func locButton(sender: AnyObject) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:AnyObject[]) {
println("locations = \(locationManager)")
var latValue = locationManager.location.coordinate.latitude
var lonValue = locationManager.location.coordinate.longitude
latLabel.text = String(latValue)
lonLabel.text = String(lonValue)
locLabel.text = "success"
}
}
If you are not much concern about high level of accuracy then you should consider startMonitoringSignificantLocationChanges instead of startUpdatingLocation. It will really make a big difference in battery draining.
This method is more appropriate for the majority of applications that just need an initial user location fix and need updates only when the user moves a significant distance. This interface delivers new events only when it detects changes to the device’s associated cell towers, resulting in less frequent updates and significantly lower power usage.
For more detail you can take a look over CLLocationManager Guide