0

I am new to Swift.

I am trying to make a two-app project, where one app contains some data files and the other accesses those files.

The solution, I think, has been to use the App Groups entitlements to allow for this, and access the files through those means. I have been able to follow along with the example here: Communicating and persisting data between apps with App Groups. In particular, the 2nd answer, which is Swift-ish (maybe an older version I guess?). It does seem to work with the right entitlements. So, now the question is how can I access the file from one app, with it being apart of the another? I'm not familiar with the API's and correct functions that I can use (new to Swift, as I said).

The apps are basic. Setup as single view applications, with everything defaulted except the ViewController's, entitlements, and one has the test data. The Xcode project structure is:

testingData/
 testingData/
  testingData.entitlements
  TestData/
   testdata.txt
  AppDelegate.swift
  ViewController.swift
  Main.storyboard
  Assets.xcassets
  LaunchScreen.storyboard
  Info.plist
 sharedContainerTest/
  sharedContainerTest.entitlements
  AppDelegate.swift
  ViewController.swift
  Main.storyboard
  Assets.xcassets
  LaunchScreen.storyboard
  Info.plist
 Products/
  testingData.app
  sharedContainerTest.app

The entitlements are both the same. They each have App Groups enabled, with the same string: group.com.example.name. On the testingData target, the ViewController has the following chunk in the viewDidLoad function from that example (modified for Swift 4.x):

var userDefaults = UserDefaults(suiteName: "group.com.example.name")!
userDefaults.set("user12345", forKey: "userId")
userDefaults.synchronize()

On the sharedContainerTest target, its ViewContoller has

var userDefaults = UserDefaults(suiteName: "group.com.example.name")
if let testUserId = userDefaults?.object(forKey: "userId") as? String {
    print("User Id: \(testUserId)")
}

in its viewDidLoad function. As I said, this seems to work, but now what do I need to add to this to access the testdata.txt file from the testingData app? Does it need to be stored as a variable, perhaps? Or is there a Bundle object that can do this?

If this has been answered elsewhere, please kindly point me to it and I'll take this down.

Lou
  • 1,113
  • 3
  • 9
  • 22

1 Answers1

0

After some trial and error, the answer is as follows:

Instead of passing in the string "user12345", you need to pass in the URL to the file you want to read for the userDefaults.set method as follows:

var userDefaults = UserDefaults(suiteName: "group.com.example.name")!
userDefaults.set(Bundle.main.url(forResource: "testdata", withExtension: ".txt"), forKey: "userId")
userDefaults.synchronize()

Then in the receiver app, you call that object and set the URL:

let userDefaults = UserDefaults(suiteName: "group.com.example.name")
let test = userDefaults?.object(forKey: "userId") as? String
let testURL = URL(fileURLWithPath: test!)

From here you can read in the contents as normal.

Lou
  • 1,113
  • 3
  • 9
  • 22