I'm creating a Swift finder sync extension that needs to read the file data into an array to send to an api but it won't read it into the array because InputStream.hasBytesAvailable()
returns false so won't enter the for loop. my app requires the app sandbox which iv'e got "User Selected Files" and "Downloads" folder given read/ write access. I've also given the app full disk access in my system settings.
This is my block of code causing the error specifically at the start of the While loop.
let filePath = "/Users/<user>/Desktop/film.mp4"
guard let inputStream = InputStream(fileAtPath: filePath) else {
print("Failed to create input stream")
return
}
// This dictates how many bytes are in each packet it must be a multiple of 327,680
let packetSize = 3276800
inputStream.open()
var buffer = [UInt8](repeating: 0, count: packetSize)
// Write data to bytesArray
while inputStream.hasBytesAvailable{
let bytesRead = inputStream.read(&buffer, maxLength: buffer.count)
if bytesRead < 0 {
print("Failed to read from input stream: \(inputStream.streamError?.localizedDescription ?? "unknown error")")
break
} else if bytesRead == 0 {
print("End of input stream reached")
break
} else {
// Process the bytes that were read
let data = Data(bytes: buffer, count: bytesRead)
bytesArray.append(data)
}
}
inputStream.close()
these errors are printed in the console when i hit the button:
- open flag(s) 0x01000000 are reserved for VFS use and do not affect behaviour when passed to sqlite3_open_v2
- cannot open file at line 46922 of [554764a6e7]
- os_unix.c:46922: (0) open(/private/var/db/DetachedSignatures) - Undefined error: 0
I have tried deleting the the app sandbox which can stop access to some files but when my app builds it doesn't run properly and my option doesn't appear in the context menu and no setup logs are printed to the console.
It works in my first app that doesn't have an app sandbox and isn't split over two targets.
Any help is much appreciated
Does anyone know if this is correct?
You are correct that:
-
Finder Sync extensions must be sandboxed.
-
Sandboxed apps (and appexes) can’t access resources outside of their sandbox.
-
The temporary exception entitlements allow you to bypass that restriction.
However, whether this is the right approach depends on the context. If you plan to ship your Finder Sync extension to the Mac App Store, it’s definitely not the right approach. My experience is that App Review takes a dim view of any use of these temporary exception entitlements.
As to what else you can do, it depends on the overall structure of your extension and its container app. The standard pattern for a Finder Sync extension is for the container app to ask the user for the directory in which they want operate. That yields a sandbox extension allowing the app to use that. The app then passes that privilege along to the appex.
For more background on this, see On File System Permissions.
ps Swift is moving away from InputStream
for reading files. The better option these days is FileHandle
. Having said that, whatever API you use will having this problem.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"