Website Links

Tuesday, 22 December 2015

Swift - Sending Emails and SMS from app

Opening up a pre-populated message composer in iOS which can be used to send an email or SMS is surprisingly easy. There is however, some issues you may encounter when testing this on a simulator where it lags and then crashes. So it is best to have a physical device available if you plan on testing this. I have also heard that having a singleton instance of your composer and showing this when required can help alleviate these issues. However, I needed to be able to send SMS/Emails based on a push notification, and on a physical device I didn't encounter these issues. Here's how I did it:

  import UIKit
  import MessageUI

  class MessageComposerViewController : UIViewController, 
    MFMailComposeViewControllerDelegate, 
    MFMessageComposeViewControllerDelegate {
    
    ...
    
    func sendEmail() {
      let emailVc = MFMailComposeViewController()
      emailVc.mailComposeDelegate = self
      emailVc.setSubject("Seasons Greetings!")
      emailVc.setMessageBody("<b>Merry Christmas!<br/>
        From Trip Wire</b>", isHTML: true)
      emailVc.setToRecipients(["hello@world.christmas"])
      presentViewController(emailVc, animated: true, 
        completion: nil)
    }

    func mailComposeController(
      controller: MFMailComposeViewController, 
      didFinishWithResult result: MFMailComposeResult, 
      error: NSError?) {
      dismissViewControllerAnimated(true, completion: nil)
    }

    func sendSms() {
      let smsVc = MFMessageComposeViewController()
      smsVc.body = "Seasons greetings! From the Trip Wire team";
      smsVc.recipients = ["5556789"]
      smsVc.messageComposeDelegate = self;
      presentViewController(smsVc, animated: true, 
        completion: nil)
    }

    func messageComposeViewController(
      controller: MFMessageComposeViewController, 
      didFinishWithResult result: MessageComposeResult) {
      dismissViewControllerAnimated(true, completion: nil)
    }

    ...

  }

Monday, 14 December 2015

Swift - Sorting NSManagedObjects (from Core Data)

Class to represent Core Data Table

You will need to add a class to represent your core data table:

  // My core data object only had the field name
  // it also had relationships but I didn't need to access 
  // these so they are excluded. 
  import CoreData

  @objc(Mode)
  class Mode: NSManagedObject {
    @NSManaged var name: String
  }

Following that you will need to ensure your core data table references the class or you'll get an error, you can do this in the same place you would add columns to the table:



Performing the sort

First you must load the data, ensure that you save it as an array of your object representation of the Core Data table.

  ...

  let modes : [Mode] = try context.executeFetchRequest(request)
    as! [Mode]

  // We must specify whether we want to sort in
  // ascending or descending order
  // $0 represents the first item, $1 represents the second
  // their fields can be access as normal 
  appState.modes = modes.sort({$0.name.compare($1.name) 
    == NSComparisonResult.OrderedAscending}) as [Mode]

  ...

Swift - try/catch

In Swift, when a func is marked with throws, it can throw an exception and your code should handle this. This can be done using do/try/catch statements as follows:

  // do contains all statements that should 
  //be executed only if the try succeeds
  do {
    // try comes before the func which is marked with throws
    let modes : [Mode] = try context.executeFetchRequest(request)
      as! [Mode]

    // tried func has succeeded, continue with workflow
    appState.modes = modes.sort({$0.name.compare($1.name) 
      == NSComparisonResult.OrderedAscending}) as [Mode]
  } catch {
    // handle error
    // can handle different types of exceptions separately by their name
  }

Sunday, 13 December 2015

Photoshop - Change colour of entirely black icon

  1. Create a new layer solidly filled with the colour you want to change the black to
  2. Go to Layer > Create Clipping Mask
  3. Your image should now be the colour selected of the layer you created a clipping mask for

Swift - My Resources

Sometimes there are articles that I find particularly useful. This page will hold them:

Friday, 11 December 2015

Swift - Creating a countdown timer

There are many situations where you may have the need to use a countdown timer. This article is aimed at helping you create one! Firstly, you will want to add a label to your storyboard and reference it through an @IBOutlet in the relevant view controller. This will display your countdown. Following that you will need the following code:

  class GameViewController: UIViewController {

    @IBOutlet var _timerLabel: UILabel!
    var _timer : NSTimer!
    ...

    override func viewDidLoad() {
      super.viewDidLoad()
      _timerLabel.text = "60"

      //the first argument is how long in seconds
      // target - where to look for the selector
      // selector - function name
      // userInfo - AnyObject, you can use this to store 
      // anything you need
      // repeats - whether or not the function should be 
      // repeatedly called
      _timer = NSTimer.scheduledTimerWithTimeInterval
       (1, target: self, selector: Selector("countDown"), 
       userInfo: nil, repeats: true)
    }

    // function called after time interval specified above
    // updates label, or stops timer and ends game if it 
    // has reached 0
    func countDown() {
      let currentCount = Int(_timerLabel.text!)
       
      if (currentCount == 0) {
        _timer.invalidate()
        gameOver()
      } else {
        _timerLabel.text = String(currentCount! - 1)
      }
    }

    ...

  }

For more information, view the reference page for NSTimer

Swift - Hide keyboard when clicking outside UITextField or return is tapped

Sometimes it can obscure the view when a user enters something in a UITextField and the keyboard stays open even after they have clicked outside the keyboard, or tapped return. The following code will help you close the keyboard when appropriate. However, first you need to set up your text field and make the appropriate view controller be its delegate, and implement UITextFieldDelegate:



The corresponding code is as follows:

  class GameViewController: UIViewController, UITextFieldDelegate {

    ...

    override func touchesBegan(touches: Set, 
      withEvent event: UIEvent?) {
      self.view.endEditing(true)
    }

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

    ...

  }

Additionally, if you have any buttons with IBActions attached to them you may need to have the line self.view.endEditing(true) in these also.