I want to write a bundle I've dragged and dropped into my project folder into a temporary file.
Previously I used fileManager.copyItem but it deleted the original.
Original code
func copyPackagedBundleToDocuments(withDestinationName dest: String) {
if let bundlePath = Bundle.main.path(forResource: embeddedBundle, ofType: nil) {
let fileManager = FileManager.default
let destPath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first!
// applicationSupportDirectory is not created by default in the sandbox, and therefore we need to make sure that it exists!
let urls = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)
if let applicationSupportURL = urls.last {
do {
try fileManager.createDirectory(at: applicationSupportURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error)
}
}
let fullDestPath = NSURL(fileURLWithPath: destPath + "/" + dest)
do {
try fileManager.copyItem(atPath: bundlePath, toPath: fullDestPath.path!)
} catch {
print(error)
}
}
}
This tells me the paths etc. are fine, since it does copy the file.
Now I want an atomic copy, so want to use Data(contentsOfFile)
So I rewrote everything:
func copyPackagedBundleToDocuments(withDestinationName dest: String) {
if let bundlePath = Bundle.main.path(forResource: embeddedBundle, ofType: nil) {
let fileManager = FileManager.default
let destPath = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true).first!
// applicationSupportDirectory is not created by default in the sandbox, and therefore we need to make sure that it exists!
let urls = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask)
if let applicationSupportURL = urls.last {
do {
try fileManager.createDirectory(at: applicationSupportURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error)
}
}
let urlPath = URL(fileURLWithPath: destPath + "/" + dest)
let dta = try? Data(contentsOf: URL(fileURLWithPath: bundlePath) )
do {
try dta.write(to: urlPath , options: .atomic)
} catch {
print ("error \(error)")
}
}
}
However the data (dta) here is nil!
I think this is because my bundle location (as follows) ends in a backslash /:
file:///Users/user/Library/Developer/CoreSimulator/Devices/37A85B0B-F2B7-4A0C-BAA7-E05A831FFAE0/data/Containers/Bundle/Application/AD665103-E256-4F6C-8248-B62D8FF9FDC8/LocalBundle.app/Bundle.bundle/
and I guess that copyItem can treat the bundle as a single file, but writing the bundle to data is somehow not possible (the path is correct, since the code using copyItem works).
For clarity the following
if let bundleURL = Bundle.main.url(forResource: embeddedBundle, withExtension: nil) {
print ( try? Data(contentsOf: bundleURL ) )
}
prints nil to the console, validating the url for the bundle.
How can I write my bundle to a file, atomically?