Thursday, October 30, 2014

Why Swift Flies for iOS Developers

I recently wrote an article for MobiForge outlining the importance of Swift and the effect it has on the industry. I also took this opportunity to compare it with Objective-C. Here is the abstract of the article:

"Now that the dust has settled somewhat on Swift, the new language on the block for developing iOS and OSX applications, we take a look at its impact and improvements over its predecessor, Objective-C. Apple claims Swift to be a modern, safe, and powerful language for developing for iOS and OSX. Just how powerful is Swift compared to the venerable Objective-C? And how does it make developing applications easier and safer? In this article, I will walk you through some of the important features in Swift and how it improves on Objective-C. In a follow up article, I will show you how you can use Swift and Objective within the same project."
Check out the full article here

Monday, October 13, 2014

Swift - Dealing with pointers in Swift

When using certain APIs in Objective-C and C, you often have to deal with pointers. For example, you can write data to the NSOutStream object using the write:maxLength: method:

-(void) writeToServer:(const uint8_t *) buf {
    [oStream write:buf maxLength:strlen((char*)buf)];

}

The write:maxLength: method takes in a pointer of type unint8_t, containing the data you want to send across the stream. The equivalent of the above function in Swift is:

func writeToServer(dataToWrite:NSData) { 
    oStream!.write(
        UnsafePointer(dataToWrite.bytes)
        maxLength: dataToWrite.length) 
}

For reading of data, in Objective-C, you would supply an array of uint8_t:

uint8_t buf[1024]; 
unsigned int len = 0; 
len = [(NSInputStream *)stream read:buf maxLength:1024];

In Swift, you can use the following:

let buf = NSMutableData(capacity: 1024) 
var buffer = UnsafeMutablePointer(buf.bytes) 
let len = (aStream as NSInputStream).read(buffer, maxLength: 1024)

Tuesday, October 07, 2014

iOS 8 - Display an alert

The UIAlertView class is deprecated in iOS8. In place of it is the more adaptive UIAlertController class. Here is a quick example of how to display an alert in iOS 8:

    func displayAlert(title:String, content:String) {
        var alertController = UIAlertController(
            title: title,
            message: content,
            preferredStyle: UIAlertControllerStyle.Alert)
        
        var okAction = UIAlertAction(
            title: "OK", style: UIAlertActionStyle.Default) {
                (action) -> Void in
                println("Tapped on OK")
        }
        
        alertController.addAction(okAction)
        self.presentViewController(alertController, animated: true, completion: nil)
    }

To display an alert, you can call the displayAlert() function like this:

self.displayAlert("Hello", content: "Hello, iOS 8")

The above will display an alert like the following:

Xcode 6 - iPhone Simulator Folder

In Xcode 6, the location of the applications on the iPhone Simulator has changed. Prior to iOS 8, the location of the Documents folder of your app can be found here:

/Users/weimenglee/Library/Application\ Support/iPhone\ Simulator/<iOS_Version>/Applications/<application_id>/Documents 

In xCode 6, the location of the simulator has changed to:

/Users/weimenglee/Library/Developer/CoreSimulator/

However, this location contains a list of folders for different types of simulators. If you go into this folder, you will see something like this:


Each folder correspond to a specific iPhone Simulator. To know which folder corresponds to which simulator, use the following command in Terminal:

Weis-Mac-mini:~ weimenglee$ xcrun simctl list
== Device Types ==
iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s)
iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5)
iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s)
iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus)
iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6)
iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2)
iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina)
iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air)
Resizable iPhone (com.apple.CoreSimulator.SimDeviceType.Resizable-iPhone)
Resizable iPad (com.apple.CoreSimulator.SimDeviceType.Resizable-iPad)
== Runtimes ==
iOS 7.0 (7.0 - Unknown) (com.apple.CoreSimulator.SimRuntime.iOS-7-0) (unavailable, runtime path not found)
iOS 7.1 (7.1 - Unknown) (com.apple.CoreSimulator.SimRuntime.iOS-7-1) (unavailable, runtime path not found)
iOS 8.0 (8.0 - 12A365) (com.apple.CoreSimulator.SimRuntime.iOS-8-0)
== Devices ==
-- iOS 7.0 --
-- iOS 7.1 --
-- iOS 8.0 --
    iPhone 4s (8C1303A2-C590-4822-BB9B-12EC32035C8C) (Shutdown)
    iPhone 5 (402C822D-567F-4F3A-B113-1499C5A7949C) (Shutdown)
    iPhone 5s (B6D71F6A-E94B-47ED-AF25-882FDEF8E6F5) (Shutdown)
    iPhone 6 Plus (5BCD1507-6F06-4D66-B71D-47670EB703B2) (Shutdown)
    iPhone 6 (00100565-4E4D-4D9A-A875-544E0A6E4F4F) (Booted)
    iPad 2 (187D75DD-824D-4381-AE2F-BDF57FEB87E0) (Shutdown)
    iPad Retina (604667D3-8366-4147-B0AD-F7840198713C) (Shutdown)
    iPad Air (01D6AEBC-F12A-47EE-82CB-0140AF117AE0) (Shutdown)
    Resizable iPhone (9C138BCD-BFB9-4AEB-A218-F0F99F678220) (Shutdown)
    Resizable iPad (4966C908-AAA7-43EC-8E3A-EADF8BFA3C05) (Shutdown)
Weis-Mac-mini:~ weimenglee$ 

In my example here, I am looking for iPhone 6, which has the device id of 00100565-4E4D-4D9A-A875-544E0A6E4F4FYou can then go into this folder and the following path shows the folder that contains all the applications installed on this simulator:

/Users/weimenglee/Library/Developer/CoreSimulator/Devices/00100565-4E4D-4D9A-A875-544E0A6E4F4F/data/Containers/Data/Application/

You can now locate your specific application and find the Documents folder:

/Users/weimenglee/Library/Developer/CoreSimulator/Devices/00100565-4E4D-4D9A-A875-544E0A6E4F4F/data/Containers/Data/Application/FD7949EA-7D39-4BC6-95F4-77F320592651/Documents/