iOS10 是否从捆绑包中删除了读取 SQLite 数据库的功能?

Did iOS10 remove the ability to read a SQLite database from the bundle?

我使用 2 个 SQLite 数据库:一个是包的一部分 并存储 static/read-only 数据(称为 Seed.sqlite),其他在首次启动时创建(或自动迁移)并用于保存用户数据(User.sqlite)。

管理只读数据库 (Seed.sqlite) 的持久存储设置有以下选项:

options[NSReadOnlyPersistentStoreOption] = true
options[NSSQLitePragmasOption] = ["journal_mode": "DELETE"]

它在 iOS 9.x 和 iOS 10 下在模拟器中运行良好,但在 设备 运行 上使用时会崩溃 iOS 10(至少是 beta 4 和 8)。

我对 User.sqlite 数据库没有任何问题。

到目前为止,上述配置使 CoreData 符合设备上的限制(即:无法编辑捆绑文件)。 在 iOS 10 上,情况似乎仍然如此:当删除上述选项时,会创建临时文件(在模拟器中 运行 时,因为在那种情况下包是可写的),并且否则,文件保持不变。 所以它的行为似乎和以前一样,但它仍然在设备上崩溃。

这里是异常发生的地方。提到 "PFUbiquityTransactionHistoryCache writePendingEntries:"。尝试在包中写一些东西可能会解释崩溃,但我不明白为什么会调用它。

Calling po $arg1 from the exception returns "Can't create support directory(无法创建目录) (空)

CoreData`developerSubmittedBlockToNSManagedObjectContextPerform:
    0x189f45ad0 <+0>:   stp    x28, x27, [sp, #-96]!
    0x189f45ad4 <+4>:   stp    x26, x25, [sp, #16]
    0x189f45ad8 <+8>:   stp    x24, x23, [sp, #32]
    0x189f45adc <+12>:  stp    x22, x21, [sp, #48]
    0x189f45ae0 <+16>:  stp    x20, x19, [sp, #64]
    0x189f45ae4 <+20>:  stp    x29, x30, [sp, #80]
    0x189f45ae8 <+24>:  add    x29, sp, #80              ; =80 
    0x189f45aec <+28>:  mov    x20, x0
    0x189f45af0 <+32>:  ldp    x21, x19, [x20]
    0x189f45af4 <+36>:  ldr    x23, [x20, #16]
    0x189f45af8 <+40>:  tbz    w23, #2, 0x189f45b08      ; <+56>
    0x189f45afc <+44>:  bl     0x186629c74               ; objc_autoreleasePoolPush
    0x189f45b00 <+48>:  mov    x22, x0
    0x189f45b04 <+52>:  b      0x189f45b0c               ; <+60>
    0x189f45b08 <+56>:  movz   x22, #0
    0x189f45b0c <+60>:  tbz    w23, #13, 0x189f45b14     ; <+68>
    0x189f45b10 <+64>:  dmb    ish
    0x189f45b14 <+68>:  mrs    x8, TPIDRRO_EL0
    0x189f45b18 <+72>:  and    x26, x8, #0xfffffffffffffff8
    0x189f45b1c <+76>:  ldr    x25, [x26, #712]
    0x189f45b20 <+80>:  ldr    x24, [x20, #24]
    0x189f45b24 <+84>:  cmp    x25, x19
    0x189f45b28 <+88>:  b.eq   0x189f45b3c               ; <+108>
    0x189f45b2c <+92>:  cbz    x24, 0x189f45b44          ; <+116>
    0x189f45b30 <+96>:  ldr    x27, [x24, #8]
    0x189f45b34 <+100>: str    x19, [x24, #8]
    0x189f45b38 <+104>: b      0x189f45b48               ; <+120>
    0x189f45b3c <+108>: movz   x27, #0
    0x189f45b40 <+112>: b      0x189f45b4c               ; <+124>
    0x189f45b44 <+116>: movz   x27, #0
    0x189f45b48 <+120>: str    x19, [x26, #712]
    0x189f45b4c <+124>: adrp   x8, 140081
    0x189f45b50 <+128>: add    x8, x8, #2616             ; =2616 
    0x189f45b54 <+132>: ldrb   w8, [x8]
    0x189f45b58 <+136>: cbnz   w8, 0x189f45cb8           ; <+488>
    0x189f45b5c <+140>: ldr    x8, [x21, #16]
    0x189f45b60 <+144>: mov    x0, x21
    0x189f45b64 <+148>: blr    x8
    0x189f45b68 <+152>: and    x8, x23, #0x4
    0x189f45b6c <+156>: tbnz   w23, #12, 0x189f45b9c     ; <+204>
    0x189f45b70 <+160>: tbnz   w23, #1, 0x189f45bf4      ; <+292>
    0x189f45b74 <+164>: cbz    x8, 0x189f45c24           ; <+340>
    0x189f45b78 <+168>: cbz    x22, 0x189f45b84          ; <+180>
    0x189f45b7c <+172>: mov    x0, x22
    0x189f45b80 <+176>: bl     0x18a0a76ac               ; symbol stub for: -[PFUbiquitySwitchboardCacheWrapper init]
    0x189f45b84 <+180>: adrp   x8, 134549
    0x189f45b88 <+184>: ldr    x1, [x8, #1568]
    0x189f45b8c <+188>: movz   w2, #0
    0x189f45b90 <+192>: mov    x0, x19
    0x189f45b94 <+196>: bl     0x186622f20               ; objc_msgSend
    0x189f45b98 <+200>: b      0x189f45c24               ; <+340>
    0x189f45b9c <+204>: cmp    x8, #0                    ; =0 
    0x189f45ba0 <+208>: cset   w8, eq
    0x189f45ba4 <+212>: cbz    x22, 0x189f45bb4          ; <+228>
    0x189f45ba8 <+216>: tbnz   w8, #0, 0x189f45bb4       ; <+228>
    0x189f45bac <+220>: mov    x0, x22
    0x189f45bb0 <+224>: bl     0x18a0a76ac               ; symbol stub for: -[PFUbiquitySwitchboardCacheWrapper init]
    0x189f45bb4 <+228>: and    x22, x23, #0x1000
    0x189f45bb8 <+232>: tbz    w23, #0, 0x189f45bcc      ; <+252>
    0x189f45bbc <+236>: mov    x0, x21
    0x189f45bc0 <+240>: bl     0x186ab6998               ; _Block_release
    0x189f45bc4 <+244>: mov    x0, x20
    0x189f45bc8 <+248>: bl     0x18a0a71fc               ; symbol stub for: -[PFUbiquityTransactionHistoryCache writePendingEntries:]
    0x189f45bcc <+252>: movz   w21, #0
    0x189f45bd0 <+256>: cbz    x22, 0x189f45c3c          ; <+364>
    0x189f45bd4 <+260>: cmp    x25, x19
    0x189f45bd8 <+264>: b.eq   0x189f45ca0               ; <+464>
    0x189f45bdc <+268>: str    x25, [x26, #712]
    0x189f45be0 <+272>: cbz    x24, 0x189f45c78          ; <+424>
    0x189f45be4 <+276>: cmp    x27, x19
    0x189f45be8 <+280>: csel   x8, xzr, x27, eq
    0x189f45bec <+284>: str    x8, [x24, #8]
    0x189f45bf0 <+288>: b      0x189f45c78               ; <+424>
    0x189f45bf4 <+292>: adrp   x8, 134548
    0x189f45bf8 <+296>: ldr    x1, [x8, #3312]
    0x189f45bfc <+300>: mov    x0, x19
    0x189f45c00 <+304>: bl     0x186622f20               ; objc_msgSend
    0x189f45c04 <+308>: cbz    x22, 0x189f45c10          ; <+320>
    0x189f45c08 <+312>: mov    x0, x22
    0x189f45c0c <+316>: bl     0x18a0a76ac               ; symbol stub for: -[PFUbiquitySwitchboardCacheWrapper init]
    0x189f45c10 <+320>: adrp   x8, 134549
    0x189f45c14 <+324>: ldr    x1, [x8, #1568]
    0x189f45c18 <+328>: movz   w2, #0
    0x189f45c1c <+332>: mov    x0, x19
    0x189f45c20 <+336>: bl     0x186622f20               ; objc_msgSend
    0x189f45c24 <+340>: tbnz   w23, #0, 0x189f45c30      ; <+352>
    0x189f45c28 <+344>: movz   w21, #0
    0x189f45c2c <+348>: b      0x189f45c3c               ; <+364>
    0x189f45c30 <+352>: mov    x0, x21
    0x189f45c34 <+356>: bl     0x186ab6998               ; _Block_release
    0x189f45c38 <+360>: movz   w21, #0
    0x189f45c3c <+364>: cmp    x25, x19
    0x189f45c40 <+368>: b.eq   0x189f45c50               ; <+384>
    0x189f45c44 <+372>: str    x25, [x26, #712]
    0x189f45c48 <+376>: cbz    x24, 0x189f45c50          ; <+384>
    0x189f45c4c <+380>: str    x27, [x24, #8]
    0x189f45c50 <+384>: tbnz   w23, #0, 0x189f45c68      ; <+408>
    0x189f45c54 <+388>: adrp   x8, 134548
    0x189f45c58 <+392>: ldr    x1, [x8, #32]
    0x189f45c5c <+396>: mov    x0, x19
    0x189f45c60 <+400>: bl     0x186622f20               ; objc_msgSend
    0x189f45c64 <+404>: b      0x189f45c78               ; <+424>
    0x189f45c68 <+408>: mov    x0, x19
    0x189f45c6c <+412>: bl     0x187aae3e8               ; CFRelease
    0x189f45c70 <+416>: mov    x0, x20
    0x189f45c74 <+420>: bl     0x18a0a71fc               ; symbol stub for: -[PFUbiquityTransactionHistoryCache writePendingEntries:]
    0x189f45c78 <+424>: tbz    w23, #13, 0x189f45c80     ; <+432>
    0x189f45c7c <+428>: dmb    ish
    0x189f45c80 <+432>: cbnz   w21, 0x189f45cdc          ; <+524>
    0x189f45c84 <+436>: ldp    x29, x30, [sp, #80]
    0x189f45c88 <+440>: ldp    x20, x19, [sp, #64]
    0x189f45c8c <+444>: ldp    x22, x21, [sp, #48]
    0x189f45c90 <+448>: ldp    x24, x23, [sp, #32]
    0x189f45c94 <+452>: ldp    x26, x25, [sp, #16]
    0x189f45c98 <+456>: ldp    x28, x27, [sp], #96
    0x189f45c9c <+460>: ret    
    0x189f45ca0 <+464>: str    xzr, [x26, #712]
    0x189f45ca4 <+468>: cbz    x24, 0x189f45c78          ; <+424>
    0x189f45ca8 <+472>: cmp    x27, x25
    0x189f45cac <+476>: b.ne   0x189f45c78               ; <+424>
    0x189f45cb0 <+480>: str    xzr, [x24, #8]
    0x189f45cb4 <+484>: b      0x189f45c78               ; <+424>
    0x189f45cb8 <+488>: adrp   x8, 134550
    0x189f45cbc <+492>: ldr    x1, [x8, #2768]
    0x189f45cc0 <+496>: mov    x0, x19
    0x189f45cc4 <+500>: bl     0x189f3ea64               ; _PFAssertSafeMultiThreadedAccess_impl
    0x189f45cc8 <+504>: b      0x189f45b5c               ; <+140>
    0x189f45ccc <+508>: bl     0x186610720               ; objc_begin_catch
    0x189f45cd0 <+512>: and    x22, x23, #0x1000
    0x189f45cd4 <+516>: orr    w21, wzr, #0x1
    0x189f45cd8 <+520>: b      0x189f45bd0               ; <+256>
    0x189f45cdc <+524>: bl     0x1866106f0               ; objc_exception_rethrow
    0x189f45ce0 <+528>: b      0x189f45c84               ; <+436>
    0x189f45ce4 <+532>: mov    x19, x0
    0x189f45ce8 <+536>: b      0x189f45cf4               ; <+548>
    0x189f45cec <+540>: mov    x19, x0
    0x189f45cf0 <+544>: tbz    w21, #0, 0x189f45cf8      ; <+552>
    0x189f45cf4 <+548>: bl     0x186610768               ; objc_end_catch
    0x189f45cf8 <+552>: mov    x0, x19
    0x189f45cfc <+556>: bl     0x186ca4ed4               ; _Unwind_Resume
    0x189f45d00 <+560>: bl     0x186610794               ; objc_terminate

这是设备崩溃日志:

0   CoreFoundation                  0x187bd81c0 __exceptionPreprocess + 124
1   libobjc.A.dylib                 0x18661055c objc_exception_throw + 56
2   CoreData                        0x189f9ff14 -[NSSQLCore externalDataReferencesDirectory] + 992
3   CoreData                        0x18a05ef44 -[NSSQLFetchRequestContext initWithRequest:context:sqlCore:] + 424
4   CoreData                        0x189f9eba4 -[NSSQLCore processFetchRequest:inContext:] + 76
5   CoreData                        0x189ea1510 -[NSSQLCore executeRequest:withContext:error:] + 504
6   CoreData                        0x189f8183c __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 4512
7   CoreData                        0x189f79f88 -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 276
8   CoreData                        0x189ea11c4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 408
9   CoreData                        0x189e9fbec -[NSManagedObjectContext executeFetchRequest:error:] + 572
10  CoreData                        0x189f50b88 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] + 456
11  CoreData                        0x189f51390 __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke + 584
12  CoreData                        0x189f53638 internalBlockToNSManagedObjectContextPerform + 92
13  libdispatch.dylib               0x186a611c0 _dispatch_client_callout + 16
14  libdispatch.dylib               0x186a6e860 _dispatch_barrier_sync_f_invoke + 84
15  CoreData                        0x189f409a8 _perform + 232
16  CoreData                        0x189f51080 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] + 188
17  CoreData                        0x189e9fbec -[NSManagedObjectContext executeFetchRequest:error:] + 572
18  MagicalRecord                   0x101b5b274 0x101b48000 + 78452
19  CoreData                        0x189f45b68 developerSubmittedBlockToNSManagedObjectContextPerform + 152
20  CoreData                        0x189f45a48 -[NSManagedObjectContext performBlockAndWait:] + 260
…

编辑

答案是否定的,你仍然可以这样做......但是如果你有一个二进制数据属性和允许外部存储,那么它会崩溃。

因此,即使允许外部存储的模型不在种子配置中,也会创建一个带有 _EXTERNAL_DATA 子文件夹的 .Seed_SUPPORT 文件夹。

所以要修复它:

  • 创建一个 .xxx_SUPPORT 文件夹(将 xxx 替换为您的 sqlite 文件的名称),在您的 xxx.sqlite 种子文件旁边
  • 中创建一个名为_EXTERNAL_DATA的子文件夹
  • 奖励:在 _EXTERNAL_DATA 中创建一个 .gitkeep 文件,以便 git 提交文件夹
  • 将该文件夹添加到 XCode,确保使用 "Create folder references" 添加它,而不是 "Create Groups"

您可能需要在 Finder 中查看隐藏文件,为此 运行:

  • 默认写入 com.apple.finder AppleShowAllFiles 是
  • killall Finder

之后您可以将其设置回否。