Shared App Groups cache not writable

I'm trying to share cached data between a tvOS app and a TVService extension. I crated an app group and get a directory based on the identifier. All works fine in the simulator. On the tvOS dev kit however the app does not have write permission the app group directory.


I realize the restrictions on tvOS but shared cache data in app groups should be possible according the FAQ:


For temporary local storage, apps may access the NSTemporaryDirectory and NSCachesDirectory in their own container, or NSCachesDirectory in a shared container.


So how do I get access to the caches in the app group container? has anybody here got this working?

Answered by toto in 78191022

Indeed I found the solution: tvOS (like iOS and OS X) automatically creates Library/Caches inside of the app group container. The app has write permission for these directories just like for Library/Caches (aka NSCachesDirectory) in the app's container. As far as I know there is no way to get this URL programatically since NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask) does only return the URL in the app's bundle.


So I reate this URL like this:


if let url = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(appGroupIdentifier) {
  var cachesURL = url.URLByAppendingPathComponent("Library", isDirectory:  true)
  cachesURL = url.URLByAppendingPathComponent("Caches", isDirectory:  true)
}


and the resulting directory is writable for the app

Accepted Answer

Indeed I found the solution: tvOS (like iOS and OS X) automatically creates Library/Caches inside of the app group container. The app has write permission for these directories just like for Library/Caches (aka NSCachesDirectory) in the app's container. As far as I know there is no way to get this URL programatically since NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask) does only return the URL in the app's bundle.


So I reate this URL like this:


if let url = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(appGroupIdentifier) {
  var cachesURL = url.URLByAppendingPathComponent("Library", isDirectory:  true)
  cachesURL = url.URLByAppendingPathComponent("Caches", isDirectory:  true)
}


and the resulting directory is writable for the app

Just wanted to share that I noticed a bug in the above old code sample, the second append was done on the wrong variable, here it is fixed and updated:

Code Block
guard let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: group) else { return }
var cachesURL = url.appendingPathComponent("Library", isDirectory: true)
cachesURL = cachesURL.appendingPathComponent("Caches", isDirectory:  false)


Right now I'm struggling to get a disk URLCache to write to the group container, it fails with:

Code Block
2021-05-24 18:46:55.879431+0100 URLCacheTestApp[95367:2519466] [logging-persist] cannot open file at line 44499 of [02c344acea]
2021-05-24 18:46:55.879495+0100 URLCacheTestApp[95367:2519466] [logging-persist] os_unix.c:44500: (0) open(/Users/me/Library/Group%20Containers/group.com.myco.MyApp/Library/Caches/Cache.db) - Undefined error: 0
2021-05-24 18:46:55.879567+0100 URLCacheTestApp[95367:2519466] NetworkStorageDB:_openDBReadConnections: failed to open read connection to DB @ /Users/me/Library/Group%20Containers/group.com.myco.MyApp/Library/Caches/Cache.db.  Error=14. Cause=unable to open database file

Shared App Groups cache not writable
 
 
Q