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?

Accepted Reply

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

Replies

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

  • I am also trying to access the same on iOS device but its giving me an error saying "Read only file system"

    Can someone enlighten me that does it has to do anything with profile or certificates? Do we need distribution profiles only or it should work for development profiles as well?

Add a Comment