How can I view finder file comments on iOS?
Ideally, I'd like to see these comments in the iOS files app.
While it appears that iCloud Drive does actually sync file comments, the Files app unfortunately has no built-in way to read these. Instead, you'll need to use a third-party app to achieve this. The following is a free, fairly straightforward (but limited—see below) approach using Scriptable:
-
Install Scriptable from the App Store
-
Launch Scriptable and press the + button in the top right to create a new script
-
Paste the following:
const file = args.fileURLs[0]
const fm = FileManager.iCloud()
if (!fm.fileExists(file)) {
QuickLook.present('Invalid file')
return
}
fm.downloadFileFromiCloud(file)
const comment = fm.readExtendedAttribute(file, 'com.apple.metadata:kMDItemFinderComment')
if (comment === null) {
QuickLook.present('Comment not found or failed to parse.')
return
}
trailer = comment.slice(comment.length - 32, comment.length)
String.prototype.hexSlice = function (start, end) {
return parseInt(this.slice(start, end).split('').map(c => ('0' + c.charCodeAt(0).toString(16)).slice(-2)).join(''), 16)
}
offsetTableStart = trailer.hexSlice(24, 32)
offsetTableOffsetSize = trailer.hexSlice(6, 7)
topObjectStart = comment.hexSlice(offsetTableStart, offsetTableStart + offsetTableOffsetSize)
topObjectLength = comment.hexSlice(topObjectStart, topObjectStart + 1) & 0x0F
if (topObjectLength === 0x0F) {
lengthPower = comment.hexSlice(topObjectStart + 1, topObjectStart + 2) & 0x0F
charsStart = topObjectStart + 2 + Math.pow(2, lengthPower)
topObjectLength = comment.hexSlice(topObjectStart + 2, charsStart)
} else {
charsStart = topObjectStart + 1
}
topObject = comment.slice(charsStart, charsStart + topObjectLength)
QuickLook.present(topObject)
-
Tap the settings/"toggle switches" icon , tap "Name," and give the script a name (e.g., "File Comments")
-
Tap "Share Sheet Inputs" and select "File URLs" (then navigate back out by pressing Back > Done)
Now, whenever you want to view the comment for a file in the Files app, you can:
-
Select the file and hit the Share icon
-
Choose the "Run Script" action and tap the script you just created (the file comment should appear in an overlay)
Unfortunately, you'll probably find that the script fails for certain comments. This is because Scriptable can't handle certain characters, and unfortunately there's no way to work around this. (The (brief) technical explanation is that Scriptable attempts to read all extended attributes as strings, but since the comment is actually binary data, it seems to stumble on certain bytes. I don't fully understand why it fails when it does—it's not just on Unicode strings—but the whole approach is a bit hacky to begin with.)
An alternative, much more robust approach would be to use Pythonista ($9.99) to directly access the extended attributes and avoid Scriptable's problematic string conversions. Here's a Python script that does what you want (create the script in Pythonista, then press the settings cog and add it under Share Extension Shortcuts):
import appex
import console
import plistlib
import ui
from objc_util import *
def main():
fp = appex.get_file_path()
if not fp:
console.hud_alert('Error: Invalid file', 'error')
return
extd_attrs = ObjCClass('NSFileManager').defaultManager().attributesOfItemAtPath_error_(fp, None)['NSFileExtendedAttributes']
if extd_attrs is None:
console.hud_alert('No extended attributes found', 'error')
return
attr_data = extd_attrs['com.apple.metadata:kMDItemFinderComment']
if attr_data is None:
console.hud_alert('No comment found', 'error')
return
attr_bytes = nsdata_to_bytes(attr_data)
comment = plistlib.readPlistFromBytes(attr_bytes)
tv = ui.TextView()
tv.text = comment
tv.editable = False
tv.present()
main()
(Note that os.getxattr
is broken in Pythonista, hence the Objective-C workaround.)
For those who are interested, here are some references for the (very, very rough) manual bplist parsing I implemented in JavaScript:
- https://medium.com/@karaiskc/understanding-apples-binary-property-list-format-281e6da00dbd
- https://github.com/joeferner/node-bplist-parser/blob/master/bplistParser.js