1

Before the update I this code worked fine:

var alphabetizedArray = [[Person]]()

    let collation = UILocalizedIndexedCollation()

    for person : Person in ContactsManager.sharedManager.contactList {
        var index = 0
        if ContactsManager.sharedManager.sortOrder == .FamilyName {
            index = collation.sectionForObject(person, collationStringSelector: "lastName")
        }
        else {
            index = collation.sectionForObject(person, collationStringSelector: "firstName")
        }
        alphabetizedArray.addObject(person, toSubarrayAtIndex: index)
    }

But now since string literal selectors are no longer alowed the code broke.

I tried to change string literal selector to Selector("lastName"), but the 'index' is always returned as -1. And I don't see any solution.

This collation method takes a property name of the given object. And Person class is really have those properties (lastName, firstName).

But how can I get this work again? Experiments with #selector gave me nothing: 'Argument of '#selector' does not refer to an initializer or method' it says. No wonder since this sectionForObject(, collationStringSelector:) takes no methods but a property names.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Vitalii Vashchenko
  • 1,777
  • 1
  • 13
  • 23
  • 1
    matt's one is also a good read: http://stackoverflow.com/a/35658335/2227743 – Eric Aya Mar 25 '16 at 11:24
  • I've seen that, but I don't see how it helps in my case. In my case I need no method as selector, but a property name for some kind of sorting. And no matter with what syntax I write this selector, that isn't working because the new syntax requires existing method names and not string literals. – Vitalii Vashchenko Mar 25 '16 at 11:30
  • But [sectionForObject](https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalizedIndexedCollation_Class/index.html#//apple_ref/occ/instm/UILocalizedIndexedCollation/sectionForObject:collationStringSelector:) takes a selector which "identifies a method returning an identifying string for object that is used in collation" so using Module.Class.method should work (maybe in your class you have to have a method returning the property instead of just trying to use the property with the new syntax? Not sure about that.) – Eric Aya Mar 25 '16 at 11:37
  • I wrote a test func in my Person class class func lastNameString() -> String { return "lastName" } And I changed selector to this #selector(Person.lastNameString). But now I have crash with error unrecognized selector sent to instance. It's a mystery. – Vitalii Vashchenko Mar 25 '16 at 11:45
  • Did you try Module.Class.method instead of just Class.method? Just a guess. Some mysteries indeed. If you actually can't find a solution for this specific question I'll re-open it. – Eric Aya Mar 25 '16 at 11:49
  • Believe me, I'm searching through google and stackoverflow for 2 days. And nothing. P.S.: Module.Class.method didn't change anything – Vitalii Vashchenko Mar 25 '16 at 11:50
  • I've reopened the question. – Eric Aya Mar 25 '16 at 11:51
  • this is example you are using http://kostiakoval.github.io/posts/swift-and-ios-sdk/? – Oleg Gordiichuk Mar 25 '16 at 11:59
  • Oleg Gordiichuk, like I said in my question, that code isn't working in Swift 2.2. – Vitalii Vashchenko Mar 25 '16 at 18:30
  • Eric D. thanks for reopening! Martin R finally got the solution! – Vitalii Vashchenko Mar 25 '16 at 18:31

2 Answers2

4

It seems to be a combination of several problems:

  • The collation must be created with UILocalizedIndexedCollation.currentCollation().
  • The object class needs an instance method returning a String.
  • The #selector must refer to that instance method, both #selector(<Type>.<method>) and #selector(<instance>.<method>) can be used.

Here is a self-contained example which seems to work as expected:

class Person : NSObject {
    let firstName : String
    let lastName : String

    init(firstName : String, lastName : String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func lastNameMethod() -> String {
        return lastName
    }
}

and then

let person = Person(firstName: "John", lastName: "Doe")
let collation = UILocalizedIndexedCollation.currentCollation()
let section = collation.sectionForObject(person, collationStringSelector: #selector(Person.lastNameMethod))
print(section) // 3

Here, both #selector(Person.lastNameMethod) and #selector(person.lastNameMethod) can be used.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

For solving of your issue at first read new documentation about Selectors in Swift2.2.

Example: Use #selector(CLASS.lastName) instead of Selector("lastName"). Where CLASS it is actual class that contains this method.

Oleg Gordiichuk
  • 15,240
  • 7
  • 60
  • 100