iOS10是否删除了从捆绑软件读取SQLite数据库的功能? [英] Did iOS10 remove the ability to read a SQLite database from the bundle?
问题描述
我使用2个SQLite数据库:一个是捆绑软件的一部分,并存储静态/只读数据(称为Seed.sqlite),另一个是在首次启动时创建的>(或自动迁移),并用于保存用户数据(User.sqlite).
I use 2 SQLite databases: one is part of the bundle and stores static/read-only data (called Seed.sqlite), the other is created on first launch (or auto-migrated) and is used to save the user data (User.sqlite).
使用以下选项设置管理只读数据库的持久性存储(Seed.sqlite):
The persistent store managing the read-only database (Seed.sqlite) is setup with the following options:
options[NSReadOnlyPersistentStoreOption] = true
options[NSSQLitePragmasOption] = ["journal_mode": "DELETE"]
它在模拟器中的iOS 9.x和iOS 10下都可以正常运行,但在运行iOS 10的设备上使用崩溃(至少是beta 4和8).
It works fine under iOS 9.x and under iOS 10 within the simulator, but it crashes when used on a device running iOS 10 (beta 4 and 8, at least).
User.sqlite数据库没有任何问题.
I don't have any issue whatsoever with the User.sqlite database.
到目前为止,以上配置使CoreData符合设备上的限制(即:捆绑文件无法编辑).在iOS 10上,似乎仍然是这种情况:删除上述选项后,将创建临时文件(在模拟器中运行时,因为在这种情况下捆绑包是可写的),否则将保持不变.因此它的行为似乎和以前一样,但是仍然会在设备上崩溃.
Up until now, the above configuration was making CoreData complying with the restrictions on a device (ie: bundle files can't be edited). On iOS 10, it still seems like this is the case: when the above options are removed, temporary files are created (when ran in the simulator, since in that case the bundle is writable), and otherwise, the file is left untouched. So it seems to behave as it did before, but it still crashes on the device.
在这里发生异常.提到"PFUbiquityTransactionHistoryCache writePendingEntries:".尝试在捆绑软件中写一些东西可能可以解释崩溃的原因,但我不知道为什么会调用它.
Here's where the exception happens. There's a mention of "PFUbiquityTransactionHistoryCache writePendingEntries:". Trying to write something in the bundle might explain the crash, but I don't see why it would be called.
从异常中调用po $ arg1返回无法创建支持目录(无法创建目录)(空)"
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
…
修改
- 在iOS 10下重新创建Seed数据库不能解决问题
- 在第一次启动时将文件从捆绑包复制到应用程序容器中(使用NSFileManager),然后使用该容器解决了此问题.但是然后,它占用了两倍的空间(捆绑软件+副本中的数据库),这是我到目前为止一直设法避免的解决方案(至少它证明了其他所有功能都可以正常工作)
推荐答案
答案是否定的,但是您仍然可以...但是,如果您具有 Binary Data 属性并带有 Allows External Storage,那么它将崩溃.
The answer is no, you can still do that… BUT if you have a Binary Data attribute with Allows External Storage, then it will crash.
因此,即使允许外部存储的模型不在种子"配置中,也会创建带有_EXTERNAL_DATA子文件夹的.Seed_SUPPORT文件夹.
Because of that, a .Seed_SUPPORT folder with a _EXTERNAL_DATA subfolder is created, even if the models that allow external storage are not in the Seed configuration.
所以要解决此问题:
- 在xxx.sqlite种子文件旁边,
- 创建一个 .xxx_SUPPORT 文件夹(将xxx替换为sqlite文件的名称)
- 在内部创建一个名为 _EXTERNAL_DATA 的子文件夹
- 奖金:在_EXTERNAL_DATA内创建一个 .gitkeep 文件,以便git提交文件夹
- 将该文件夹添加到XCode,确保使用创建文件夹引用"而不是创建组"添加它
- create a .xxx_SUPPORT folder (replace xxx with the name of your sqlite file), next to your xxx.sqlite seed file
- create a subfolder named _EXTERNAL_DATA inside
- BONUS: create a .gitkeep file inside _EXTERNAL_DATA, so that git commits the folder
- add that folder to XCode, make sure to add it with "Create folder references", not "Create Groups"
您可能需要在Finder中查看隐藏的文件,因为它只能运行:
You'll probably need to see hidden files in the Finder, for that just run:
- 默认写com.apple.finder AppleShowAllFiles是
- killall Finder
之后您可以将其设置回NO.
You can set it back to NO afterwards.
这篇关于iOS10是否删除了从捆绑软件读取SQLite数据库的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!