20

In our iOS app we utilize a shared container to share files between our main iOS app and its extension (specifically WatchKit Extension), using [NSFileManager containerURLForSecurityApplicationGroupIdentifier:] method. For debugging purposes we need to access the content of this shared container, so we've tried to export the whole App container using the Devices window in Xcode:

Screenshot from Xcode

But, the Shared storage is not included in the container, probably because it sits in a different path on the Device itself.

The question is how can we get the shared container, if this is even possible?

Jay Mehta
  • 1,431
  • 19
  • 40
Sagi Iltus
  • 1,130
  • 10
  • 21

7 Answers7

9

I've been told by Xcode team members at WWDC that this is not possible (at time of writing, Xcode 7.3 & 8 beta 1). I've filed a radar, which I recommend everyone dupe or comment on so we can get this functionality.

Brian Gerstle
  • 3,643
  • 3
  • 22
  • 22
6

Workaround for actual device -

I generally pause the execution of my app and then run following command in lldb debugger to copy the desired file from shared container to my sandbox container and then I download the container from Xcode.

po [[NSFileManager defaultManager] copyItemAtPath:[[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:GROUP_NAME] URLByAppendingPathComponent:FILE_NAME].path toPath:[[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:FILE_NAME] path] error:nil]

Above might look complex but if you break the above, we are doing 3 things -

  1. Get shared container file

    [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:GROUP_NAME] URLByAppendingPathComponent:FILE_NAME].path

  2. Get sandbox document directory path:

    [[[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:FILE_NAME] path]

  3. Copy file from Shared container to sandbox

    [[NSFileManager defaultManager] copyItemAtPath:SHARED_PATH toPath:SANDBOX_PATH error:nil]

Sandy
  • 3,021
  • 1
  • 21
  • 29
6

For Swift 4 - 5 add this to applicationDidEnterBackground(_ application: UIApplication)

var appGroupIdentifier = "XXXXXXX"
let fromURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
let docURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let toURL = docURL.appendingPathComponent(appGroupIdentifier)
try? FileManager.default.removeItem(at: toURL)
try? FileManager.default.copyItem(at: fromURL, to: toURL)

Then download the app container using xcode.

Dmih
  • 530
  • 6
  • 9
1

I'm using this code to print out in the console the path to my local SQLite database:

NSString *groupContainer = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.myapp.mycontainer"] path];
NSString *sqlitePath = [NSString stringWithFormat:@"%@/Database.sqlite", groupContainer];
NSURL *url = [NSURL fileURLWithPath:sqlitePath];

I then copy and paste the string in the Finder -> Go to so I go directly to the folder. This works fine in the Simulator but I don't think you're able to access the your iPhone's shared container group from your Mac.

BalestraPatrick
  • 9,944
  • 4
  • 30
  • 43
  • 2
    Thanks @BalestraPatrick, I'm aware of the Simulator solution, but we need a solution for real devices for after-the-fact log crunching from beta tester devices. – Sagi Iltus Apr 20 '15 at 08:14
1

Copy your data from the group container to document directory. Then download the app container using xcode.

NSFileManager.defaultManager().copyItemAtURL(url, toURL: NSURL.fileURLWithPath(AppDelegate.applicationUserDirectory()))

url here can be obtained using below function of NSFileManager

func containerURL(forSecurityApplicationGroupIdentifier groupIdentifier: String) -> URL?
Vishun
  • 132
  • 5
  • your variable here url, what would this be if trying to access the Default location of a realm db i.e. one that's visible under Documents after showing Package Contents? – user2363025 Jan 11 '17 at 11:25
  • @user2363025 you can copy all the contents of container into document directory then choose what you want to check. – Vishun Jan 26 '17 at 19:16
0

The best solution I've found is creating a backup of your device and then using iExplorer to explore the backup. There are bunch of AppDomainGroup-* folders. Though for some reason not all of the files there are backed up (probably because of applied settings to files to be ignored during backup).

Nekto
  • 17,837
  • 1
  • 55
  • 65
0

Updated Sandy's response to swift in lldb and usage of appGroup

(lldb) po FileManager.default.copyItem(at: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.name")!.appendingPathComponent("filename"), 
to: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!.appendingPathComponent("filename"))

Another thing is that you may need to remove file from the app folder if it's been copied before otherwise the command above will fail