When working with maps, 2 of the most common operations are the search of locations and getting the name of a certain direction based on its coordinates
A quick and easy way to get this by using a CLGeocoder object which is inside MapKit framework.
Firstly, let’s search an address and we will get a list of matches. This matches will be an array of CLPlacemark object where it has the details of a location, such as, street, city, country, etc. We need to use a String parameter with the address we want to search and the method geocodeAddressString(_ addressString: String, completionHandler: CoreLocation.CLGeocodeCompletionHandler) will return a list of address or an error.
In general the errors will appear because no locations where found, but you can check the amount of listed placemarks or if it is null. There’s a limitation of use and after a few times (Apple doesn’t specify how many) it will return a kCLErrorNetwork error.

let geocoder = CLGeocoder()
let text = "Chamartin"
geocoder.geocodeAddressString(text) { (placemarks, error) in
     guard let placemarks = placemarks, placemarks.count > 0 else {
          // not found
     }
            
     placemarks.forEach({ (placemark) in
          // do something
     })
}

If we want to center the search in a certain region, we can use the method geocodeAddressString(_ addressString: String, in region: CLRegion?, completionHandler: CoreLocation.CLGeocodeCompletionHandler) where we can indicate the region using a CLRegion object.

let geocoder = CLGeocoder()
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude:40.4168, longitude:3.7038), radius: 10000, identifier: "")
let text = "Chamartin"
geocoder.geocodeAddressString(text, in: region) { (placemarks, error) in
     guard let placemarks = placemarks, placemarks.count > 0 else {
          // not found
     }
            
     placemarks.forEach({ (placemark) in
          // do something
     })
}

We can also use the address formatted using the ContactBook style, that way it will be easier to identify each field. To do that we will use the method func geocodeAddressDictionary(_ addressDictionary: [AnyHashable : Any], completionHandler: CoreLocation.CLGeocodeCompletionHandler). In order to use CNPostalAddress keywords import Contacts must be added to your code.

let dic = [CNPostalAddressStreetKey:"Gran Via", CNPostalAddressCityKey:"Madrid"]
geocoder.geocodeAddressDictionary(dic) { (placemarks, error) in
     guard let placemarks = placemarks, placemarks.count > 0 else {
          // not found
     }
            
     placemarks.forEach({ (placemark) in
          // do something
     })
}

Finally, with the method func reverseGeocodeLocation(_ location: CLLocation, completionHandler: CoreLocation.CLGeocodeCompletionHandler) we can get the oppossite result, that is, the address from a given coordinate.

let geocoder = CLGeocoder()
let location = CLLocation(latitude:40.4168, longitude:3.7038)
geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
     guard let placemarks = placemarks, placemarks.count > 0 else {
          // not found
     }
            
      placemarks.forEach({ (placemark) in
          // do something
     })
}

Do you want to this working? Click here to see the whole project

With iOS8 Apple released interactive notifications, which are the notifications we already know but where users can interact with. Notification allow you to add custom button to let the user do an action, i.e. delete an email directly from the notification.
As part of the interactive notifications Apple released UIMutableUserNotificationAction and UIMutableUserNotificationCategory too, which are the actions of a notification and the category of them respectively.
First, you need to define the action or actions included in the notification. To do that we can use this code:

let action = UIMutableUserNotificationAction()
action.identifier = "notification_identifier"
action.title = "Push it!"

Now you have to create the category to which the action will belong:

let category = UIMutableUserNotificationCategory()
category.identifier = "category_identifier"
category.setActions([action], forContext: .Default)

There are 2 types of ways to assign actions to a category, previous example is using Default (forContext: .Default) and this indicates the actions that will be available if the notification is shown as a popup. It is also available the type called Minimal (forContext: .Minimal) which will show the actions in the lock screen and also as a banner. It is recommended to use both versions because the lock screen and the banner only allows 2 actions.

Once the action and the category are created it’s time to ask for permision to the user to send notifications:

if let categories = NSSet(object: category) as? Set {
    let types: UIUserNotificationType = [.Alert, .Sound, .Badge]
    let settings = UIUserNotificationSettings(forTypes: types, categories: categories)
    UIApplication.sharedApplication().registerUserNotificationSettings(settings)
}

Now we only need to send a notifications sending the category parameter we want to use:

let localNotification = UILocalNotification()
localNotification.fireDate = NSDate().dateByAddingTimeInterval(3)
localNotification.alertBody = "New UILocalNotification"
localNotification.category = "category_identifier"

UIApplication.sharedApplication().scheduledLocalNotifications = [localNotification]

Or if you are sending a notification from a server, the payload must include the parameter "category":"your_category_key":

{"aps":{"alert":"Hello Testing","badge":1,"sound":"default"}}

Obviously we need to handle user’s answer and to do that we need to use the method func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) or func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void).
Using identifier as the identifier of the category and notification.identifier or userInfo["identifier"] as the identifier of the notification we know which action the user clicked.

Up to here you have the basic logic to work with interactive notifications but improve them is not rocket science.

Do you want the app to stay in background when the user pushes an option because you are handling the response in backgroud? Using the attribute activationMode from UIMutableUserNotificationAction you can indicate that the action should be performed in background.

action.activationMode = .Background

What if the action is performed in background but we need to access a local DB which is locked when the device is locked? Easy, use the attribute authenticationRequired from UIMutableUserNotificationAction

action.authenticationRequired = true

The color of the buttons is controller by iOS and by default it’ll be blue or a dark gray but you have the chance to make it red using this attribute destructive from UIMutableUserNotificationAction

action.destructive = false

When iOS 9 was released, Apple introduced new options to interactive notifications, such as, a text field to type inside the notification using the attribute behavior from UIMutableUserNotificationAction

action.behavior = .TextInput

By default, the text field will include a button with a text Send, but you can easily customize it using this code:

action.parameters = [UIUserNotificationTextInputActionButtonTitleKey:"Save"]

The way to access the text introduced by the user is using some methods introduced in iOS 9 but really similar to the ones used in iOS 8 func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) or func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void). To control the option clicked by the user we can use the same method as before, I mean, using the identifier, but to access the text you need to use the parameter responseInfo:

let text = responseInfo[UIUserNotificationActionResponseTypedTextKey]

UITableView elements can be boring because its functionality is very limited, because you can only click on a cell and control that event in func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) but that has changed since iOS8 thanks to UITableViewRowAction
UITableViewRowAction allows you add hidden actions to a UITableViewCell easily and it will appear the same way as the default delete button.
Each cell can have many actions and to do that you need to overwrite the method tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? from UITableViewDelegate.

Next example show how to include a button that writes a message in the console.

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let more = UITableViewRowAction(style: .Default, title: "More") { action, index in
        print("more button tapped")
    }
    return [more]
}

There are 3 styles available (Default, Destructive y Normal) where the main difference is the background color, but that color can be changed easily. Unfortunately there’s no way to use an image as a background or a gradient color that is available.

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let more = UITableViewRowAction(style: .Default, title: "More") { action, index in
        print("more button tapped")
    }
    more.backgroundColor = .lightGrayColor()
    return [more]
}

But, luckily for us, we can use an image as a pattern, convert that into a color and use it as the background.

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let more = UITableViewRowAction(style: .Default, title: "More") { action, index in
        print("more button tapped")
    }
    more.backgroundImage = UIColor(patternImage: UIImage(named: "plusIcon.png"))
    return [more]
}

Text can’t be replaced by and image unless we use one of the emoticons included in xcode or unicode characters

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
        let more = UITableViewRowAction(style: .Default, title: "\u{2B}\nMore") { action, index in
            print("more button tapped")
        }
  more.backgroundColor = .lightGrayColor()
        return [more]
}

You can add as many buttons as you need but have in mind that the list of buttons can’t be wider that the cell itself otherwise buttons won’t be accessible.

func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let more = UITableViewRowAction(style: .Default, title: "\u{2B}\nMore") { action, index in
        print("more button tapped")
    }
    more.backgroundColor = .lightGrayColor()
    let share = UITableViewRowAction(style: .Destructive, title: "\u{260F}\nCall now") { action, index in
        print("share button tapped")
    }
    share.backgroundColor = UIColor.blueColor()    
    return [more, share]
}

Do you want to this working? Click here to see the whole project

One of the most important features in Xcode are the Storyboards. With them, implement the user interface of an app and make it available across different device resolutions is really easy, but if we use our own classes everything is different because the visualization doesn’t work as expected.

To help us with this, we can use the IBDesignable and IBInspectable labels.

@IBDesignable allows the class to be visualized in the Storyboard

@IBDesignable class MMACustomView: UIView {
    private var label = UILabel()
    
    @IBInspectable var text: String?
    @IBInspectable var textColor: UIColor?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        buildUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        buildUI()
    }
    
    func buildUI() {
        addSubview(label)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        refreshUI()
    }
    
    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        refreshUI()
    }
    
    private func refreshUI () {
        label.text = text
        label.textColor = textColor
        label.sizeToFit()
        label.center = center
    }
}

@IBInspectable allows the properties to appear in the Attributes Inspector and implementing the method prepareForInterfaceBuilder() changes will appear in real time.

IBDesignable-IBInspectable

Do you want to this working? Click here to see the whole project

MMACodeReader is a UIView subclass with a AVCaptureVideoPreviewLayer added as a sublayer and a UIView used to square the code once it is read.

The AVCaptureVideoPreviewLayer uses a AVCaptureSession that controls when the video stream starts/stops. This AVCaptureSession has a AVCaptureDeviceInput that uses default camera in video input by default using this code:

let captureDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
do {
  let input = try AVCaptureDeviceInput(device: captureDevice)
  avCaptureSession.addInput(input)
} catch {
  print(error)
  return
}

To recognize all supported codes the AVCaptureSession uses a AVCaptureMetadataOutput as output.

let captureMetadataOutput = AVCaptureMetadataOutput()
avCaptureSession.addOutput(captureMetadataOutput)
captureMetadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode]

Finally to wrap all we just need to add the AVCaptureVideoPreviewLayer into the layer we want to use as the previewer.

avCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: avCaptureSession)
avCaptureVideoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
self.layer.addSublayer(avCaptureVideoPreviewLayer!)
avCaptureSession.startRunning()

As you may notice, AVCaptureMetadataOutput has a delegate used once a code is read by firing the method public func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) and the way to parse the read code is:

if let metadataObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
    let barCodeObject = avCaptureVideoPreviewLayer?.transformedMetadataObjectForMetadataObject(metadataObj)
    if metadataObj.stringValue != nil {
        print(metadataObj.stringValue)
    }
} else {
    print("Code Not Recognized")
}

One more thing, enjoy it!