Запрос в Realm (с использованием Swift)

Я играю с realm.io. Я написал пару объектов, и теперь я хочу запросить их. Мой класс данных:

class Sample : RLMObject {
    dynamic var sampleKey : String = ""
}

и мой код запроса

@IBAction func readLocalRecord(sender: UIButton) {

    let s : NSString = NSString.stringWithString("sampleKey == SampleValue")
    let p : NSPredicate = NSPredicate(format: "sampleKey = %@", argumentArray: NSArray(object: NSString.stringWithString("SampleValue")))

    // the following throws exception, that I cannot catch in Swift:
    //   'Unsupported predicate value type', reason: 'Object type any not supported'
    let r = Sample.objectsWithPredicate(p)
}

На веб-странице и в заголовке RLMObject указано, что я должен иметь возможность сказать Sample.objectsWhere("sampleKey = 'SampleValue'") (или подобное), но objectWhere выдает ошибку компиляции, жалуясь, что функции нет, и есть нет автозаполнения для него. Поэтому я попытался вместо этого использовать objectsForPredicate, но это говорит о том, что тип «любой» (копаясь в заголовках, я обнаружил, что это соответствует типу «id» ObjC в жаргоне Realm). Что я здесь делаю неправильно? Я стараюсь быть очень явным, обязательно использую NSString вместо String и NSArray вместо Array, но все же что-то интерпретируется как «id» вместо определенного типа.

Какие-либо предложения?

Ваше здоровье

-Ник


person niklassaers    schedule 08.08.2014    source источник


Ответы (2)


Ваш код отлично работает для меня с Xcode 6 beta 5. Кстати, вам не нужно явно использовать здесь NSArray и NSString - Swift подключится к типам Objective-C для вас. Следующее работает для меня и распечатывает объект, который я ожидаю увидеть:

import Realm

class Sample : RLMObject {
    dynamic var sampleKey : String = ""
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func readLocalRecord() {

        // create some sample records
        RLMRealm.defaultRealm().beginWriteTransaction()
        var s = Sample()
        s.sampleKey = "Testing"
        RLMRealm.defaultRealm().addObject(s)
        var s2 = Sample()
        s2.sampleKey = "SampleValue"
        RLMRealm.defaultRealm().addObject(s2)
        RLMRealm.defaultRealm().commitWriteTransaction()

        let p : NSPredicate = NSPredicate(format: "sampleKey = %@", argumentArray: [ "SampleValue" ])

        let r = Sample.objectsWithPredicate(p)
        println(r)
    }

    func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {

        readLocalRecord()

        return true
    }
}

Выход:

RLMArray <0x7fe8241218c0> (
    [0] Sample {
        sampleKey = SampleValue;
    }
}

Обратите внимание, что метод Realm objectsWithPredicate возвращает вам массив Realm, а не обычный массив.

person James Frost    schedule 08.08.2014

NSArray всегда будет возвращать эквивалент [AnyObject]? Даже указав тип строки, когда вы ее создаете, другие объекты не обязательно будут знать тип, если можно предположить более одного.

Я бы попробовал создать массив типа [String] и передать его вместо этого или использовать NSPredicate, который принимает аргументы напрямую ( predicateWithFormat:arguments: ), а не в массиве - возможно, это сработает?

Наконец, я не знаком с областью, но я нашел шаблон, если что-то недоступно в Swift, это то, что оно доступно, но есть еще один способ сделать это. например есть ли массив объектов в RLMObject? Если это так, вы можете использовать objects.filter({ $0.key == value }) или полный блок (который позволяет выполнять отладку с помощью точек останова и т. д., что я лично предпочитаю использовать NSPredicates.

person James Alvarez    schedule 08.08.2014