Unified Contacts

29 August, 2015

advance(startIndex, n) is change to Index.advancedBy(n)

In Xcode 7 Beta 6 global function advance(startIndex, n) is no longer available. You must use Index.advancedBy(n) to get the same result. advance(startIndex, n) is very useful in substringing. Since you cannot pass an Int to the Index type in substring function.

Prior to Xcode 7 Beta 6
var str = "abc"
firstChar = str.substringToIndex(advance(str.startIndex, 1))   // a

Xcode 7 Beta6
var str = "abc"
firstChar = str.substringToIndex(str.startIndex.advancedBy(1))  // a

15 April, 2015

Default Behavior of UIPopoverPresentationController Changed in iOS 8.3

I have working with an adaptive app that can run on all size class. Before updating to iOS 8.3, the popover behavior is the same in iPad and iPhone 6 Plus landscape mode. However, after updating to iOS 8.3, the popover in iPhone 6 Plus has changed to FormSheet. This is because the popover now not only check the horizontal size class, but also the vertical size class. Popover will present normally in vertical regular like iPad, and present as FormSheet in vertical compact. So how can we fix it?

Below is the old method to disable the adaptivity of popover in horizontal compact. But it not enough in iOS 8.3.

In the demo of WWDC 2014 Session 214 "View Controller Advancements in iOS 8", Bruce explained a trick that let you present popover in horizontal compact environment (e.g. iPhone). Without this trick, the popover will be presented in modal. Let take a look what is the trick.

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.None
}

This function in UIAdaptivePresentationControllerDelegate can modify the UIModalPresentationSytle when the device is changed from horizontal regular to horizontal compact. By return .None, popover will no longer adaptive to horizontal compact and will presented in popover just like that in horizontal regular.

Okay, we now know that popover check now check both horizontal and vertical size class. Therefore, we need to use a new funcation. Apple introduced a new function in iOS 8.3 which let you determine the UIModalPresentationStyle by the TraitCollection.

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!, traitCollection: UITraitCollection!) -> UIModalPresentationStyle {
    return UIModalPresentationStyle.None

}

This new function can be used to replace the old function. I have disabled the adaptivity of popover in whatever size class and everything works just like in iOS 8.2.

Reference: iOS 8.3 API Diffs

12 April, 2015

Problem When Appending Tuple into Array

I've got the following error message when trying to append a tuple into an array.

Missing argument for parameter #2 in call

Here is my tuple
    (String, UInt64, NSDate?)

I get the tuple from another function and then append to the array

var fileRecords: [(String, UInt64, NSDate?)]?

var tuple = createArchive()
self.records!.append(tuple!)    <- error here

However, if I assign the tuple to a constant first and then append that constant to array. It is work.

var tuple = createArchive()
let aTuple = tuple!
self.records!.append(aTuple)    <- Okay

15 March, 2015

Element Name in Tuple only Local Significant

Tuple is a new data type in Swift. It can group multiple values of different type of data into a single tuple. It is useful when you want to return multiple values in a function.

There is an example in the Swift document from Apple, you can give elements a name when you create the tuple.

let http200Status = (statusCode: 200, description: "OK")

println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"


The element name makes the code more readable and meaningful. However, the name can only be used within the scope. If you get a tuple that returned from a function. The element name will be removed. The element can be gotten by index number of the element.

func getHttp200Status() -> (Int, String) {
    let http200Status = (statusCode: 200, description: "OK")

    return http200Status
}

var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")


Elements are numbered from 0 and autocomplete will tell you what is inside the tuple.



Tuple是Swift的新資料類型. 它可以把多個不同資料類型的值組合在一個tuple內. 當你想function回傳多個值時, 這個會很有用.

這裡有一個範例在Apple的Swift文件. 當創建一個tuple時, 你可以給予每一個元素一個名字.

let http200Status = (statusCode: 200, description: "OK")

println("The status code is \(http200Status.statusCode)")
// prints "The status code is 200"
println("The status message is \(http200Status.description)")
// prints "The status message is OK"


這個名字能令你的code可讀性更高及更有意思. 不過, 這個名字只可以在scope內使用. 如果你由一個function取得一個tuple, 元素的名字會被移除. 而元素仍能以索引數字取得.

func getHttp200Status() -> (Int, String) {
    let http200Status = (statusCode: 200, description: "OK")

    return http200Status
}

var status = getHttp200Status()
println("The status code is \(http200Status.statusCode)")
// '(Int, String)' does not have a member named 'statusCode'
println("The status code is \(http200Status.0)")


元素索引由0開始, 自動完成會告訴你有甚麼元素在tuple裡.