How to Create and Access Share App Group Document Directory

how can I create and access share app group document directory?

Solved

  let fileManager = FileManager.default
let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.companyname.appname")?.appendingPathComponent("logo.png")

// store image in group container
if !fileManager.fileExists(atPath: url!.path) {

let image = UIImage(data: data)
let imageData : Data = UIImagePNGRepresentation(image!) as! Data
fileManager.createFile(atPath: url!.path as String, contents: imageData, attributes: nil)
}

//ACCESS THIS or get store image
let Image1 = UIImage(contentsOfFile: (url?.path)!)!

Create directory in app group container swift

containerURLForSecurityApplicationGroupIdentifier returns the URL to the group container.

To create a directory append the new directory name as path component

let fileManager = NSFileManager.defaultManager()
if let directory = fileManager.containerURLForSecurityApplicationGroupIdentifier("APP_GROUP_IDENTIFIER") {
let newDirectory = directory.URLByAppendingPathComponent("MyDirectory")
try? fileManager.createDirectoryAtURL(newDirectory, withIntermediateDirectories: false, attributes: nil)
}

Swift 3:

let fileManager = FileManager.default
if let directory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "APP_GROUP_IDENTIFIER") {
let newDirectory = directory.appendingPathComponent("MyDirectory")
try? fileManager.createDirectory(at: newDirectory, withIntermediateDirectories: false, attributes: nil)
}

How to add files to an App Group shared directory?

The issue was actually using [url absoluteString] vs [url path], changing all the urls to path solved the permissions error.

How to find Apple App Group shared directory

EDIT on 2018-10-12: Updated code for Swift 4.x (Xcode 10). (Older version retained for reference.)

In Swift 4.x:

let sharedContainerURL :URL? = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.etc.etc")
// replace "group.etc.etc" above with your App Group's identifier
NSLog("sharedContainerURL = \(String(describing: sharedContainerURL))")
if let sourceURL :URL = sharedContainerURL?.appendingPathComponent("store.sqlite") {
if let destinationURL :URL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("copyOfStore.sqlite") {
try! FileManager().copyItem(at: sourceURL, to: destinationURL)
}
}

In older version of Swift (probably Swift 2.x):

let sharedContainerURL :NSURL? = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.etc.etc")  // replace "group.etc.etc" with your App Group's identifier
NSLog("sharedContainerURL = \(sharedContainerURL)")
if let sourceURL :NSURL = sharedContainerURL?.URLByAppendingPathComponent("store.sqlite")
{
if let destinationURL :NSURL = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0].URLByAppendingPathComponent("copyOfStore.sqlite")
{
try! NSFileManager().copyItemAtURL(sourceURL, toURL: destinationURL)
}
}

Something like the above will get a file from the app group's shared container to the app's Documents directory. From there, you could use Xcode > Window > Devices to get it to your computer.

You could also use iTunes file sharing to retrieve the file from the app's Documents directory after setting UIFileSharingEnabled to YES in the Info.plist file, but bear in mind that this will expose the directory's contents to the user as well. Should be okay for development/debugging purposes, though.

How can app extension access files in containing app Documents/ folder

In order to make files available to app extension you have to use Group Path, as App Extension can't access app's Document Folder, for that you have follow these steps,

  1. Enable App Groups from Project Settings-> Capabilities.
  2. Add a group extension something like group.yourappid.
  3. Then use following code.

    NSString *docPath=[self groupPath];

    NSArray *contents=[[NSFileManager defaultManager] contentsOfDirectoryAtPath:docPath error:nil];

    NSMutableArray *images=[[NSMutableArray alloc] init];

    for(NSString *file in contents){
    if([[file pathExtension] isEqualToString:@"png"]){
    [images addObject:[docPath stringByAppendingPathComponent:file]];
    }
    }

    -(NSString *)groupPath{
    NSString *appGroupDirectoryPath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:group.yourappid].path;

    return appGroupDirectoryPath;
    }

You can add or change the path extension as per your image extensions you are generating.

Note - Remember you need to generate the images in the group folder rather than in Documents Folder, so it is available to both app and extension.

Cheers.

Swift 3 Update

let fileManager = FileManager.default
let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "YOUR_GROUP_ID")?.appendingPathComponent("logo.png")

// Write to Group Container
if !fileManager.fileExists(atPath: url.path) {

let image = UIImage(named: "name")
let imageData = UIImagePNGRepresentation(image!)
fileManager.createFile(atPath: url.path as String, contents: imageData, attributes: nil)
}

// Read from Group Container - (PushNotification attachment example)
// Add the attachment from group directory to the notification content
if let attachment = try? UNNotificationAttachment(identifier: "", url: url!) {

bestAttemptContent.attachments = [attachment]

// Serve the notification content
self.contentHandler!(self.bestAttemptContent!)
}

Two apps in one device and the image uploaded from first app will appear in the second app

Yes you can share some data within groups of app as per new updates in iOS 8.0 and above.

Just you need to create apps group and share your data among that groups app.

Below are few steps to enable app groups.

Step1: Enable App group from Target Setting -> Capabilities -> App Group

Sample Group name : groups.companyname or groups.appgroupname

Sample Image

Note: Every app which you want in this group must have same group name
in this section.

Step 2: Get General sharing folder where you can store shared data like images DB.

for that you need to get path of that shared folder as mention below

Objective-C :

- (NSString *)getSharedGroupFolderPath:(NSString*)aAppGroupName {
NSURL *aContainerPathURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:aAppGroupName];
return [aContainerPathURL relativePath];
}

Swift:

static func appGroupContainerURL() -> URL? {
// 1
let fileManager = FileManager.default
guard let groupURL = fileManager
.containerURL(forSecurityApplicationGroupIdentifier: <APP_GROUP_NAME>) else {
return nil
}

let storagePathUrl = groupURL.appendingPathComponent("File Provider Storage")
let storagePath = storagePathUrl.path
// 2
if !fileManager.fileExists(atPath: storagePath) {
do {
try fileManager.createDirectory(atPath: storagePath,
withIntermediateDirectories: false,
attributes: nil)
} catch let error {
print("error creating filepath: \(error)")
return nil
}
}
// 3
return storagePathUrl

}

By above method you can get Group container folder path now save your data here which you need to share among multiple Apps.

Step3:

Store your image of file on container path like below

guard let destinationURL = TestFileViewController.fileUrlForDocumentNamed("FileName") else {
return
}

let image = UIImage.init(named: "tests")

if !FileManager.default.fileExists(atPath: destinationURL.path) {

do {
try UIImageJPEGRepresentation(image!, 1.0)!.write(to: destinationURL)
print("file saved")
} catch {
print("error saving file")
}
} else {
print("file already exists")
}

Use below supported method for getting file path :

// Returns the file URL for the file to be saved at
static func fileUrlForDocumentNamed(_ name: String) -> URL? {
guard let baseURL = appGroupContainerURL() else { return nil }

let protectedName: String
if name.isEmpty {
protectedName = "Untitled"
} else {
protectedName = name
}

return baseURL.appendingPathComponent(protectedName)
.appendingPathExtension("your file extension")
}

Hope this will helps you to achieve your requirements.

iOS 8 - Share Documents Directory Between Apps

No, you cannot have a shared documents directory, but you can have a shared folder in which you can use as your documents directory. When you create an app group Create an identifier for each of your apps in the app group.

Then you can use the file manager to get the URL for the directory you want with the given group identifier.

let url = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.MTC.DataSender")!

This will return the URL to the directory for the DataSender app. Every app in the app group can access this directory. So in your other app you would do the same thing.



Related Topics



Leave a reply



Submit