Tuesday, September 30, 2014

Swift - Calling Objective-C code

In Xcode 6, you now have the option to create a project using either Swift or Objective-C. In addition, you can also use Objective-C code in your Swift project. This post shows you how. 

1. First, create an iOS project that uses the Swift language

2. Add a Objective-C File file to your project. Name it as MyClass

3. You will be prompted with the following:


4. This will add a file named UsingObjC-Bridging-Header.h to your project. Behind the scene, Xcode automatically sets the Objective-C Bridging Header setting to this file:


5. Add a Header File file to your project. Name it as MyClass

6. Populate the MyClass.h with the following:

#import

@interface MyClass: NSObject

@property (strong, nonatomic) NSString *property;

- (void) method;

@end

7. Populate the MyClass.m with the following:

#import "MyClass.h"

@implementation MyClass

- (void) method {
    NSLog(@"In method now");
}

@end

8. Populate the UsingObjC-Bridging-Header.h with the following:

#import "MyClass.h"

9. To use the Objective-C class that you have added to your project, add the following statements in bold to the ViewController.swift file:

    override func viewDidLoad() {
        super.viewDidLoad()

        // create an instance of the class
        var myClass: MyClass = MyClass()

        // set its property
        myClass.property = "some random strings here"

        // call its method
        myClass.method()
        
        // retrieve its property
        println(myClass.property)

    }

Monday, September 29, 2014

Swift - Checking if a method exists

A lot of changes has happened in iOS 8, and a lot of APIs require that you call certain new methods before they can work. Examples are locations, notifications, and more.

To ensure that your app can work on older versions of iOS as well as the new iOS 8, it is important that you only call the new API when your app is running on iOS 8. The best way is to test if a method exists. You can do so via the respondsToSelector() method. The following example tests to see if the UIApplication object contains the registerUserNotificationSettings() method:

if application.respondsToSelector("registerUserNotificationSettings") {

}

Another example:

if self.locationManager.respondsToSelector("requestAlwaysAuthorization") {


}

iOS 8 - Displaying Local Notifications

Displaying local notifications has changed a little in iOS 8. You now need to seek the user's permission in order to display notifications. You can do so via the AppDelegate, like this:

    func application(application: UIApplication
    didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        application.registerUserNotificationSettings(
            UIUserNotificationSettings(
                forTypes:
                UIUserNotificationType.Sound |
                UIUserNotificationType.Alert |
                UIUserNotificationType.Badge, categories: nil))
            
        return true

    }


Once user's permission is granted, you would now be able to display a notification as usual:

        var localNotification =  UILocalNotification()
        //---the message to display for the alert---
        localNotification.alertBody =
            "You have entered the region you are monitoring"
        
        //---uses the default sound---
        localNotification.soundName = UILocalNotificationDefaultSoundName
        
        //---title for the button to display---
        localNotification.alertAction = "Details"
        
        //---display the notification---

        UIApplication.sharedApplication().presentLocalNotificationNow(localNotification)

Sunday, September 28, 2014

Swift - Using Selector in Swift

In Objective-C, you often encounter methods that accepts a Selector as the argument. A good example is the NSTimer's NSTimer.scheduledTimerWithTimeInterval() method:

- (void)onTimer {
}

    [NSTimer scheduledTimerWithTimeInterval:0.05
                                     target:self
                                   selector:@selector(onTimer)
                                   userInfo:nil
                                    repeats:YES];   


A selector is basically a name of a method that will be executed by another method. In Objective-C, to pass in a selector argument you use the @selector() keyword together with the name of the method. 

In Swift, you can simply pass in the name of the method as a string, like this:

func onTimer() {
}

        NSTimer.scheduledTimerWithTimeInterval(0.05,
            target:self,
            selector:"onTimer",
            userInfo:nil,
        repeats:true)

Swift - Generating a random number

If you want to generate a random number in Swift, use the arc4random_uniform() function. The following code snippet generates a number from 0 to 9:

var i = Int(arc4random_uniform(10))

Thursday, September 25, 2014

iOS 8 - Getting Location Data

Getting location data in iOS 8 has changed drastically. Here is what you need to do if you are using the CLLocationManager class to get a location in iOS 8.

In iOS 8, you need to add the following two keys in your info.plist file:

For getting location in the foreground

Key
NSLocationWhenInUseUsageDescription

Value
"This app will display your current location" (up to you to write anything you want here)

For getting location in the background

Key
NSLocationAlwaysUsageDescription

Value
"This app will log your location into a database" (up to you to write anything you want here)

Before you use the startUpdatingLocation() method, you have to request for user's permission. To use the location in the foreground, call the requestWhenInUseAuthorization() method:

var lm: CLLocationManager!
...
        if (UIDevice.currentDevice().systemVersion as NSString).floatValue>=8.0 {            
            //---request for foreground location use---
            lm.requestWhenInUseAuthorization()
        }
        
        lm.startUpdatingLocation()


If you want to continue getting location data in the background, call the requestAlwaysAuthorization() method:

        if (UIDevice.currentDevice().systemVersion as NSString).floatValue>=8.0 {
            //---request for background location use---
            lm.requestAlwaysAuthorization()
        }


Note that if you want the app to access location information both in the foreground and in the background, it is sufficient to call the requestAlwaysAuthorization() method.

Saturday, September 13, 2014

Schedule for Oct to Dec 2014 Released

I am happy to announce the new schedule for courses from Oct to Dec 2014.

Sep 2014
Sun
Mon
Tue
Wed
Thu
Fri
Sat

1
2
3
4
5
6

7
8
S$699/pax
9-10
S$1,097/pax
11
S$699/pax
12
S$699/pax
13

14
15-16
S$1,097/pax
17
S$699/pax
18-19
S$1,495/pax

20

21
22-23
S$1,097/pax
24-25
S$1,097/pax
26
S$699/pax
27
28
29-30 Sep, 1 Oct
S$1,695/pax




Oct 2014

Sun
Mon
Tue
Wed
Thu
Fri
Sat

29-30 Sep, 1 Oct
S$1,695/pax
2
S$699/pax
3
4

5
6
7-8
S$1,097/pax
9-10
S$1,097/pax

11

12
13-14
S$1,097/pax
15
16-17
S$1,395/pax
18

19
20
21
22
23
24
25

26
27
28
29
30
31



Nov 2014
Sun
Mon
Tue
Wed
Thu
Fri
Sat






1


2
3
4
5
6
7
8


9
10-11
S$1,097/pax
12-13
S$1,097/pax
14
15


16
17
18
19
20
S$699/pax
21
S$699/pax
22


23


24
25
26
27
28
29
30








Dec 2014

Sun
Mon
Tue
Wed
Thu
Fri
Sat

1-2
S$1,097/pax
3-4
S$1,097/pax
5
S$699/pax
6


7
8-9
S$1,097/pax
10
S$699/pax
11
S$699/pax
12
13


14
15
16
17


18
19
20

21

22-23
S$1,495/pax
24


25
26
S$699/pax
27
28

29-30
S$1,097/pax
31