简体   繁体   中英

Querying in Realm (using Swift)

I'm toying with realm.io. I've written a couple of objects, and now I want to query for them. My data class:

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

and my query code

@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)
}

The webside, and the header of RLMObject, indicate that I should be able to say Sample.objectsWhere("sampleKey = 'SampleValue'") (or similar), but objectsWhere gives a compile error complaining the function isn't there, and there's no autocomplete for it. So I tried with objectsForPredicate instead, but this says that the type 'any' (digging through the headers, I find that this equals ObjC's 'id' type in Realm lingo). What am I doing wrong here? I try to be veery explicit, being sure to use NSString instead of String and NSArray instead of Array, but still something is interpreted as 'id' instead of a spesific type.

Any suggestions?

Cheers

-Nik

Your code works fine for me with Xcode 6 beta 5. Incidentally, you don't need to explicitly use NSArray and NSString here - Swift will bridge to objective-c types for you. The following works for me and prints out the object I'd expect to see:

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
    }
}

Output is:

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

Note that Realm's objectsWithPredicate method returns you a Realm array, not a normal Array.

An NSArray will always return the equivalent of [AnyObject]? Even specifying the type of string, when you create it, other objects won't necessarily know the type, if more than one can be assumed.

I would try creating an array of type [String] and passing that instead, or using the NSPredicate that takes arguments directly ( predicateWithFormat:arguments: )rather than in an array - perhaps this would work?

Lastly, I'm not familiar with realm, but a pattern I've found, if something isn't available in swift is that it is available but that there's just another way to do it. eg is there an 'objects' array on the RLMObject ? If so you could do objects.filter({ $0.key == value }), or a full block (which allows debugging with breakpoints etc - which I personally prefer to using NSPredicates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM