Reputation: 7584
I have a sharing extension that accepts URLs. When I use the Google
app on iOS, in certain circumstances, it provides a file with a type identifier public.plain-text
. However, when I try to decode that as plain text, e.g., using (item
below is an NSItemProvider
):
item.loadFileRepresentation(forTypeIdentifier: "public.plain-text") { (url, error) in
if let error = error {
logger.error("\(error)")
return
}
guard let url = url else {
logger.error("No url found")
return
}
guard let data = try? Data(contentsOf: url) else {
logger.error("No data loaded from URL")
return
}
guard let string = String(data: data, encoding: .utf8) else {
logger.error("No string loaded from URL; data.count: \(data.count); \(data)")
return
}
logger.debug("string from text file: \(string)")
}
This fails on the conversation to a .utf8 String.
What is the format of this file? And what does it contain?
Upvotes: 1
Views: 260
Reputation: 7584
I looked at file with an ascii decoding and the first few bytes were bplist00
-- which seems to be a binary plist (e.g, see https://medium.com/@karaiskc/understanding-apples-binary-property-list-format-281e6da00dbd).
Then, I tried decoding the file using:
item.loadDataRepresentation(forTypeIdentifier: "public.plain-text") { (data, error) in
if let error = error {
logger.error("\(error)")
return
}
guard let data = data else {
logger.error("No data")
return
}
guard let plist = try? PropertyListSerialization.propertyList(from: data, format: nil) else {
logger.error("No data")
return
}
let dict = plist as? [String: Any]
logger.debug("plist: \(plist); dict: \(dict)")
logger.debug("string from text file: \(string)")
}
Here's the output:
2021-01-12T21:02:18-0700 debug : plist: {
"$archiver" = NSKeyedArchiver;
"$objects" = (
"$null",
"https://www.reddit.com/r/MacOS/comments/kvv21j/macos_malware_used_runonly_applescripts_to_avoid/"
);
"$top" = {
root = "<CFKeyedArchiverUID 0x28241e5a0 [0x1e7041b20]>{value = 1}";
};
"$version" = 100000;
}; dict: Optional(["$archiver": NSKeyedArchiver, "$top": {
root = "<CFKeyedArchiverUID 0x28241e5a0 [0x1e7041b20]>{value = 1}";
}, "$version": 100000, "$objects": <__NSCFArray 0x283109dc0>(
$null,
https://www.reddit.com/r/MacOS/comments/kvv21j/macos_malware_used_runonly_applescripts_to_avoid/
)
])
So, it looks like I can index into this resulting dictionary and get the URL.
Upvotes: 2