Swift 2 examples – #5 Getting the User’s Location

This post is part of my collection: Swift 2 – For Beginners.

In this example we will see how to get the user’s location and we will update our map with it.

We will use the setMapLocation method that we created in Swift 2 examples – #3 Set the location of a MapView

To get the user’s location we need the CoreLocation.framework, the first thing that we should do is to add it to our project:
Add CoreLocation framework

Then we import the CoreLocation in our controller and implement CLLocationManagerDelegate

// 2 Import CoreLocation
import CoreLocation
// 3 Implement CLLocationManagerDelegate
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
...

The next step will be to create and run the location manager:

    // 4 Create Location manager
    var locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
  
        // 5 Configure and start the location manager
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest // GPS
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }

It is worth to mention this line locationManager.requestWhenInUseAuthorization().

It will shows a popup asking for permission to access the location, we can show a message within it to explain the user why.
AskUser for permissions

The message that will be shown has to be defined in the Info.plist

   	<key>NSLocationWhenInUseUsageDescription</key>
	<string>This is a message displayed to the user to ask for location permissions.</string>

	<key>NSLocationAlwaysUsageDescription</key>
	<string>This is a message displayed to the user to ask for permissions to get the location in background.</string>

If the user allows the location access this method will be called in the delegate when the application detect a location change.

    // 6 Called when the phone detect a new location
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 
        let userLocation: CLLocation = locations[0]
        
        MapHelper.setMapLocation(mapView: self.map, location: userLocation.coordinate, zoom: 0.01)
    }

The method has as a parameter an array of locations, it contains always at least one object representing the current location. If updates were deferred or if multiple locations arrived before they could be delivered, the array may contain additional entries.

All the code of this example together:

import UIKit
import MapKit

// 1 Add CoreLocation.framework to the project

// 2 Import CoreLocation
import CoreLocation

// 3 Implement CLLocationManagerDelegate
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet weak var map: MKMapView!
    
    // 4 Create Location manager
    var locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
  
        // 5 Configure and start the location manager
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest // GPS
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
    
    // 6 Called when the phone detect a new location
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation: CLLocation = locations[0]
        
        MapHelper.setMapLocation(mapView: self.map, location: userLocation.coordinate, zoom: 0.01)
    }
}

One last thing worth to mention is that the iOS emulator supports different location simulation modes. It helps a lot during development.
Location and the Emulator

Advertisements

Swift 2 examples – #4 Add user annotations to a MapView

This post is part of my collection: Swift 2 – For Beginners.

In this example we will see how to add an annotation to our map when the user tap and hold.

UserCreatedAnnotation

Before we create annotations you should add a MapView to your application, you can see how to do it here.

To detect when the user tapped and hold on the screen we can use the recognizer: UILongPressGestureRecognizer. The next method adds a long press recognizer to our map.

It has 4 parameters:

  • The map where the gesture recognized will be added.
  • Target, the class that has the action to be executed.
  • Action, the selector of the function that will be executed when the gesture is recognized.
  • tapDuration, the time in seconds that the user has to hold the tap before the action is executed, by default 1 second.
    static func addOnUserTapAction(mapView mapView: MKMapView, target: AnyObject, action: Selector, tapDuration: Double = 1){
      
        // Adding a colon at the end of the selector we pass the recognizer that triggered the action to the action
        let longPressRecognizer = UILongPressGestureRecognizer(target: target, action: action)
        longPressRecognizer.minimumPressDuration = tapDuration
        
        // Add gesture recognizer to the map
        mapView.addGestureRecognizer(longPressRecognizer)
    }

Now we can use the method in our controller:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        ...
        
        // Adding a colon at the end of the selector we pass the recognizer that triggered the action to the action
        MapHelper.addOnUserTapAction(mapView: map, target:self, action: "addAnnotation:")
    }

The method addAnnotation will be executed when our recognizer is fired, it will add an annotation to our map:

    func addAnnotation(gestureRecognizer:UIGestureRecognizer){
        print("add annotation")
        
        let location = MapHelper.getTappedLocation(mapView: self.map, gestureRecognizer: gestureRecognizer)
        
        // Add an annotation
        let annotation = MKPointAnnotation()
        annotation.coordinate = location;
        annotation.title = "You created this annotation!"
        map.addAnnotation(annotation)
    }
  

The last thing that we have to do is to write a method to get the coordinate in the map using the point on the screen where the user tapped:

    static func getTappedLocation(mapView mapView: MKMapView, gestureRecognizer: UIGestureRecognizer) -> CLLocationCoordinate2D{
        
        // Get the position on the screen where the user pressed, relative to the mapView
        let touchPoint = gestureRecognizer.locationInView(mapView)
        
        // Get location coordinate in map
        return mapView.convertPoint(touchPoint, toCoordinateFromView: mapView)
    } 

Swift 2 examples – #3 Set the location of a MapView

This post is part of my collection: Swift 2 – For Beginners.

In this example we will see how to set the location of a MKMapView.

The first thing that we should do is to go to the storyboard and add a Map Kit View to our view:
MapKitView

Before we can use the map view there are a few things that we have to do:

  1. Import MapKit
  2. Make our controller implement MKMapViewDelegate
  3. Add an IBOutlet to our MKMapView
import UIKit
// 1) Import MapKit
import MapKit

// 2) This controller will be the delegate of our mapView
class ViewController: UIViewController, MKMapViewDelegate {

    // 3) Outlet to a MapView in our storyboard
    @IBOutlet weak var map: MKMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 4) Set location of the map: Fuengirola - Malaga 36.5417° N, 4.6250° W
        MapHelper.setMapLocation(mapView: map, latitude: 36.548628, longitud: -4.6307649)
    }
}

Now we can implement a method that we can reuse to set the location of our maps. The method setMapLocation will have 4 parameters:

  • mapView, map that will show our location
  • latitud of our location
  • longitud of our location
  • zoom level, by default if not specified will be 1
    static func setMapLocation(mapView mapView: MKMapView, latitude: CLLocationDegrees, longitud: CLLocationDegrees, zoom: Double = 1){
        
        // define the map zoom span
        let latitudZoomLevel : CLLocationDegrees = zoom
        let longitudZoomLevel : CLLocationDegrees = zoom
        let zoomSpan:MKCoordinateSpan = MKCoordinateSpanMake(latitudZoomLevel, longitudZoomLevel)
        
        // use latitud and longitud to create a location coordinate
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitud)
        
        // define and set the region of our map using the zoom map and location
        let region:MKCoordinateRegion = MKCoordinateRegionMake(location, zoomSpan)
        mapView.setRegion(region, animated: true)
        
    }

Swift 2 examples – #2 Close keyboard after edit

This post is part of my collection: Swift 2 – For Beginners.

iOS applications show automatically the keyboard when you click on a text field. The keyboard hides the bottom of your application and is not closed automatically.
In this example we will see how to close the keyboard when the user tap “Return” or touch out of the text field.

Close keyboard when the user touch out of the text field

This is pretty easy, just add this code to your view controller:

    // close keyboard when the user touch somewhere 
    // that is not the keyboard of the text field
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }

Close keyboard when the user tap Return

To do this our view controller has to implement the interface UITextFieldDelegate:

  class ViewController: UIViewController, UITextFieldDelegate

Then we set our view controller as the delegate of our text field:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // this controller is the UITextFieldDelegate of our text field
        self.insertNameField.delegate = self
    }

Now we have access to a function that will be called always that the user tap “Return”. That function is “textFieldShouldReturn(textField: UITextField) -> Bool”.

To close the keyboard we resign the edition to the first responder:

    // Implement delegate UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool{
        textField.resignFirstResponder()
        return true
    }

This is the complete code of our view controller:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var insertNameField: UITextField!
    @IBOutlet weak var usernameLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // this controller is the UITextFieldDelegate of our text field
        self.insertNameField.delegate = self
    }
    
    @IBAction func confirmName(sender: AnyObject) {
        usernameLabel.text = "Hello " + insertNameField.text!
    }

    // Implement delegate UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool{
        textField.resignFirstResponder()
        return true
    }
    
    // close keyboard when the user touch somewhere 
    // that is not the keyboard of the text field
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
}


Swift 2 examples – #1 Loading an image from a URL

This post is part of my collection: Swift 2 – For Beginners.

In this example we will see how to load an image from a URL in a UIImageView. With the new version of iOS 7 it is not possible to make requests to non secure URLs, in other words the URL must be https and not http.

The first thing that we have to do to load images from a non secure URL is to add this to our Info.plist file:

	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

The loadImageFromUrl method will have two parameters:

  • url: String – URL of the image to load
  • view: UIImageView – View where the image will be loaded
    static func loadImageFromUrl(url: String, view: UIImageView){
        
        // Create Url from string
        let url = NSURL(string: url)!
        
        // Download task:
        // - sharedSession = global NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage objects.
        let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (responseData, responseUrl, error) -> Void in
            // if responseData is not null...
            if let data = responseData{
                
                // execute in UI thread
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    view.image = UIImage(data: data)
                })
            }
        }
        
        // Run task
        task.resume()
    }

Using the previous method we can very easily load an image from a URL inside our UIImageView. This is a nice page to get sample images http://dummyimage.com

class ViewController: UIViewController {
    @IBOutlet weak var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        ImageHelper.loadImageFromUrl("http://dummyimage.com/200x200/000333/d2d4fa.png&text=Hello+Swift!", view: imageView)
    }
}

Hello Swift