Uploaded image for project: 'Realm Cocoa SDK'
  1. Realm Cocoa SDK
  2. RCOCOA-1774

Realm package as a dynamic framework

      Problem

      We have an SDK which depends on Realm and we distribute it as an XCFramework.
      When our clients include this xcframework into their projects, they are seeing a lot of logs similar to this one:

      (Let's say our SDK name is OurSDK and our client's project is ClientProject)

      Class RLMAppConfiguration is implemented in both /.../DerivedData/ClientProject/.../OurSDK.framework/OurSDK (0x112b46fb0) and /.../CoreSimulator/.../ClientProject.app/ClientProject (0x10c9a89a8). One of the two will be used. Which one is undefined.

      We understand the reason for this is because Realm is statically linked to both the XCFramework and the Client's project, and having Realm as a dynamic framework would solve the issue.

      Also, the app is crashing at some point with the following stacktrace:

      *** Terminating app due to uncaught exception 'RLMException', reason: 'null
      Exception backtrace:
      0   OurSDK                           0x000000010dd74bc2 _ZN5realm15InvalidTableRefC2EPKc + 58
      1   OurSDK                           0x000000010dd74a6c _ZNK5realm13ConstTableRef5checkEv + 62
      2   OurSDK                           0x000000010dd79511 _ZN5realm9TableView7do_syncEv + 205
      3   OurSDK                           0x000000010dc785ea _ZN5realm5Query8find_allERKNS_18DescriptorOrderingE + 246
      4   OurSDK                           0x000000010dbbd9f6 _ZN5realm7Results17ensure_up_to_dateENS0_12EvaluateModeE + 476
      5   OurSDK                           0x000000010dbbd90c _ZN5realm7Results17ensure_up_to_dateENS0_12EvaluateModeE + 242
      6   OurSDK                           0x000000010dbc5094 _ZN5realm7Results24evaluate_query_if_neededEb + 58
      7   OurSDK                           0x000000010d9dee64 -[RLMResults countByEnumeratingWithState:objects:count:] + 49
      8   libswiftFoundation.dylib            0x00007fff5999eb82 $s10Foundation25NSFastEnumerationIteratorV4nextypSgyF + 258
      9   OurSDK                           0x000000010da81abe block_destroy_helper.47 + 4766
      10  OurSDK                           0x000000010d6845ef block_destroy_helper + 40159
      11  OurSDK                           0x000000010d661d9d __swift_destroy_boxed_opaque_existential_0 + 4173
      12  OurSDK                           0x000000010d66130e __swift_destroy_boxed_opaque_existential_0 + 1470
      13  OurSDK                           0x000000010d69fa88 __swift_memcpy24_8 + 16712
      14  OurSDK                           0x000000010d6c8bb3 block_destroy_helper + 9123
      15  OurSDK                           0x000000010d6c7cb7 block_destroy_helper + 5287
      16  OurSDK                           0x000000010d6cc7da block_destroy_helper + 810
      17  OurSDK                           0x000000010d838005 __swift_memcpy153_8 + 5797
      18  OurSDK                           0x000000010d839dce __swift_memcpy153_8 + 13422
      19  OurSDK                           0x000000010d839dfb __swift_memcpy153_8 + 13467
      20  OurSDK                           0x000000010de8eb66 __swift_memcpy0_1 + 24822
      21  OurSDK                           0x000000010de99d3e __swift_memcpy0_1 + 70350
      22  OurSDK                           0x000000010de99aa5 __swift_memcpy0_1 + 69685
      23  OurSDK                           0x000000010de78ac5 __swift_memcpy40_8 + 127461
      24  OurSDK                           0x000000010de99b50 __swift_memcpy0_1 + 69856
      25  OurSDK                           0x000000010de72a13 __swift_memcpy40_8 + 102707
      26  OurSDK                           0x000000010de28020 block_destroy_helper + 1072
      27  OurSDK                           0x000000010de28110 block_destroy_helper + 1312
      28  OurSDK                           0x000000010de03fb6 __swift_memcpy16_8 + 310
      29  OurSDK                           0x000000010de03a60 __swift_noop_void_return + 2944
      30  OurSDK                           0x000000010de6fce0 __swift_memcpy40_8 + 91136
      31  OurSDK                           0x000000010d83964c __swift_memcpy153_8 + 11500
      32  OurSDK                           0x000000010d838a61 __swift_memcpy153_8 + 8449
      33  OurSDK                           0x000000010d83b999 __swift_memcpy153_8 + 20537
      34  OurSDK                           0x000000010d858153 block_destroy_helper + 48931
      35  OurSDK                           0x000000010d783fe5 __swift_assign_boxed_opaque_existential_1 + 72437
      36  OurSDK                           0x000000010d77ea8d __swift_assign_boxed_opaque_existential_1 + 50589
      37  OurSDK                           0x000000010d7964a8 block_destroy_helper + 1608
      38  OurSDK                           0x000000010d7787d2 __swift_assign_boxed_opaque_existential_1 + 25314
      39  CFNetwork                           0x00007fff23e48782 CFNetwork + 30594
      40  CFNetwork                           0x00007fff23e63ed8 _CFHTTPMessageSetResponseProxyURL + 16299
      41  libdispatch.dylib                   0x000000010b1d1816 _dispatch_call_block_and_release + 12
      42  libdispatch.dylib                   0x000000010b1d2a5b _dispatch_client_callout + 8
      43  libdispatch.dylib                   0x000000010b1d93bd _dispatch_lane_serial_drain + 855
      44  libdispatch.dylib                   0x000000010b1da123 _dispatch_lane_invoke + 490
      45  libdispatch.dylib                   0x000000010b1e6601 _dispatch_workloop_worker_thread + 907
      46  libsystem_pthread.dylib             0x00007fff701c7074 _pthread_wqthread + 326
      47  libsystem_pthread.dylib             0x00007fff701c5ffb start_wqthread + 15'
      terminating with uncaught exception of type NSException
      

      Would it be possible to have Realm as a dynamic framework for SPM?

      Solution

      Probably the solution for this would be to declare two new different products in Package.swift, like:

      ...
      products: [
        .library(
          name: "Realm",
          targets: ["Realm"]),
        .library(
          name: "RealmSwift",
          targets: ["Realm", "RealmSwift"]),
        .library(
          name: "Realm-Dynamic",
          type: .dynamic,
          targets: ["Realm"]),
        .library(
          name: "RealmSwift-Dynamic",
          type: .dynamic,
          targets: ["Realm", "RealmSwift"]
        )
      ],
      ...
      

      I'm not sure about dependencies like RealmDatabase probably we would need a "RealmDatabase-Dynamic" as well.

      How important is this improvement for you?

      Dealbreaker

            Assignee:
            Unassigned Unassigned
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: