realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.27k stars 2.14k forks source link

Include RealmSwift files directly in project #2962

Closed SandyChapman closed 8 years ago

SandyChapman commented 8 years ago

I'm attempting to include the RealmSwift source files directly into my app and using a the Realm static framework. The reason being that I want to utilize RealmSwift while retaining support for targeting iOS 7. I've gotten this to compile, however, I'm hitting an issue when I attempt to do anything using Realm at runtime.

I'm getting the following error:

2015-12-08 14:33:25.311 NewUI[14089:5533882] +[NewUI.Test requiredProperties]: unrecognized selector sent to class 0x108e7c7c0
2015-12-08 14:33:33.645 NewUI[14089:5533882] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NewUI.Test requiredProperties]: unrecognized selector sent to class 0x108e7c7c0'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010a869f45 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010a1a5deb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010a87246d +[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x000000010a7bfeea ___forwarding___ + 970
    4   CoreFoundation                      0x000000010a7bfa98 _CF_forwarding_prep_0 + 120
    5   NewUI                               0x0000000108b6760b +[RLMObjectSchema propertiesForClass:isSwift:] + 1855
    6   NewUI                               0x0000000108b66343 +[RLMObjectSchema schemaForObjectClass:] + 428
    7   NewUI                               0x0000000108bcd33f +[RLMSchema registerClasses:count:] + 854
    8   NewUI                               0x0000000108bcc5c2 +[RLMSchema schemaWithObjectClasses:] + 179
    9   NewUI                               0x0000000108adccbc _TTOFCSo9RLMSchemaCfMS_FT13objectClassesGSaPSs9AnyObject___S_ + 92
    10  NewUI                               0x0000000108adcc40 _TFFVC5NewUI5Realm13Configurations11objectTypesGSqGSaMCS_6Object__U_FGSaMS2__CSo9RLMSchema + 80
    11  NewUI                               0x0000000108adcd0d _TTRXFo_oGSaMC5NewUI6Object__oCSo9RLMSchemazoPSs9ErrorType__XFo_iGSaMS0___iS1_zoPS2___ + 45
    12  NewUI                               0x0000000108adbf09 _TPA__TTRXFo_oGSaMC5NewUI6Object__oCSo9RLMSchemazoPSs9ErrorType__XFo_iGSaMS0___iS1_zoPS2___ + 89
    13  libswiftCore.dylib                  0x000000010c9f1671 _TFSq3mapu__rfGSqq__FzFzq_qd__GSqqd___ + 401
    14  NewUI                               0x0000000108adb680 _TFVC5NewUI5Realm13Configurations11objectTypesGSqGSaMCS_6Object__ + 176
    15  NewUI                               0x0000000108adaea9 _TFVC5NewUI5Realm13ConfigurationCfMS1_FT4pathGSqSS_18inMemoryIdentifierGSqSS_13encryptionKeyGSqCSo6NSData_8readOnlySb13schemaVersionVSs6UInt6414migrationBlockGSqFT9migrationCS_9Migration16oldSchemaVersionS3__T__11objectTypesGSqGSaMCS_6Object___S1_ + 1113
    ...
)
libc++abi.dylib: terminating with uncaught exception of type NSException

This happens even not utilizing the Swift Realm classes and use the Objective-C classes instead. If I add the following line to the RealmSwift.Object class, the code will execute and the error is avoided:

public class func requiredProperties() -> [String] { return [] }

Is there any danger in doing this to get around the crash? Am I missing anything? What typically provides the definition for this requiredProperties call that I'm overlooking? If I'm looking to implement this method myself in my classes, what should be returned?

Thanks.

tgoyne commented 8 years ago

Realm Swift has never been tested on iOS 7 specifically due to that it's designed with the assumption that it'll be used as a Swift module, and we strongly recommend that you use the Objective-C API with RLMSupport.swift if you need to target iOS 7.

requiredProperties doesn't exist in the RealmSwift version of Object because in Swift you can just directly declare properties as optional or not optional, while in obj-c there's no (reasonable) way to put that into the property definition. However, your subclasses are being treated as obj-c classes because there's several places in the obj-c code where we look up classes defined in the Swift code by their fully-qualified names, and this is failing because your app is presumably not named RealmSwift. At the minimum you'll need to replace all of the occurrences of "RealmSwift" in the source for Realm.framework with the name of the target that the Swift code is being compiled in to.

bdash commented 8 years ago

The +requiredProperties message is only intended to be sent to Objective-C classes. The fact it's being sent to a Swift class suggests that either we're incorrectly detecting the language of the class (see the first few lines of +[RLMObjectSchema schemaForObjectClass:]), or that RealmSwift isn't loaded (leading to RLMObjectUtilClass returning RLMObjectUtil rather than RealmSwift.ObjectUtil). Given your comment about the non-standard way you're building RealmSwift, I suspect it's the latter.

SandyChapman commented 8 years ago

@tgoyne @bdash : Thanks for the tips. Since I've already invested a bit in using the Swift version of the API, I'll see if I can adapt it to my project's target. If not, I'll have to fall back onto using the ObjC API. I'll follow up shortly on my progress with details in case anyone else is looking to do something similar.

jpsim commented 8 years ago

Since you're using Realm in a way we explicitly don't support, I'll close this issue. However, please do share what you end up doing, I'm sure we're all curious to see!

SandyChapman commented 8 years ago

@jpsim @tgoyne @bdash : So I have this working. I have yet to run the unit tests, but the changes to support using RealmSwift in any Swift module is pretty simple. A total of 5 lines changed. This also shouldn't break support in the existing RealmSwift module. Are you guys interested in me contributing this? Since it's not explicitly supported I'd understand if you didn't want a PR, but if you do, I can go through the PR process (figured I'd ask before wasting time on it)

SandyChapman commented 8 years ago

@jpsim @tgoyne @bdash

See my diff here: https://github.com/lixar/realm-cocoa/commit/20cf23548afba2ccd618c9a26d8a9ed5a3714759

Let me know if you want a PR and on which branch you'd like it on (you guys have a lot of them).