如何反序列化照片 plist 的 IPXDefaultLibraryURLBookmark
How to deserialize the IPXDefaultLibraryURLBookmark of the Photos plist
所以,我一直在尝试反序列化 com.apple.Photos 默认值 (defaults read com.apple.Photos IPXDefaultLibraryURLBookmark
) 的 IPXDefaultLibraryURLBookmark,但没有成功。理想情况下,我希望在 C++ 中以编程方式反序列化该值以检索照片的最后已知位置
bookd0xUsersmateuscbPicturesPhotos Library.photoslibrary 0@˜ì5$r$Éò|åú¨A∫˙æJ file:///Macintosh HDÇ1tA∫‘}•65C0A4-1771-3C89-9055-147CEDFBBF2EÅÔ/∆72cd528f2dcfb4b3434986cf3caa02cc946333b8;00000000;00000000;0000000000000020;com.apple.app-sandbox.read-write;00000001;01000004;0000000002980783;/users/mateuscb/pictures/photos library.photoslibrary¥˛ˇˇˇdº‰@‘ î H ( 8 t0 †–Ä®
我知道它不是 bplist
,因为第一个格式说明符表示 bookd
。
但我不知道那是什么。我对 OSX 开发有些陌生,所以这可能是我所缺少的非常基本的东西。
我想检索:/users/mateuscb/pictures/photos library.photoslibrary
部分以便找到默认照片库。
除非有另一种方法来检索默认的照片库路径?
我想出了如何检索 .photoslibrary 的路径。我使用 CFURLCreateByResolvingBookmarkData
从 plist 中获取 CFURLRef
,然后使用 CFURLGetFileSystemRepresentation
获取字符串形式的完整路径。
通过此示例帮助检索沙盒首选项:https://gist.github.com/glebd/4759724
这是我的完整解决方案:
int main(int argc, const char * argv[]) {
bool success = FALSE;
UInt8 photosUrlString[PATH_MAX];
struct passwd *pwd = getpwuid(getuid());
if (pwd == NULL){
Log("Unable to retrieve current user");
return 0;
}
const char *home = pwd->pw_dir;
if (home == NULL){
Log("Unable to retrieve current user directory");
return 0;
}
CFMutableStringRef preferencesPath = CFStringCreateMutable(NULL, 0);
if (preferencesPath) {
CFStringAppend(preferencesPath, CFStringCreateWithCStringNoCopy(NULL, home, kCFStringEncodingUTF8, NULL));
CFStringAppend(preferencesPath, CFSTR("/Library/Containers/com.apple.Photos/Data/Library/Preferences/com.apple.Photos"));
} else {
Log("Unable to create CFString of user directory");
return 0;
}
CFPropertyListRef photosUrlPrefs = CFPreferencesCopyValue(CFSTR("IPXDefaultLibraryURLBookmark"), preferencesPath, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
CFRelease(preferencesPath);
if (photosUrlPrefs) {
CFTypeID prefsType = CFGetTypeID(photosUrlPrefs);
if (CFDataGetTypeID() == prefsType) {
CFDataRef photosUrlData = (CFDataRef) photosUrlPrefs;
CFErrorRef urlResolveError = nil;
CFURLRef photosUrl = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, photosUrlData, NULL, NULL, NULL, NULL, &urlResolveError);
if (photosUrl == NULL) {
if(urlResolveError != NULL) {
CFStringRef resolveErrorString = CFErrorCopyDescription(urlResolveError);
if (resolveErrorString != NULL) {
char resolveErrorCString[PATH_MAX];
if (CFStringGetCString((CFStringRef) resolveErrorString, resolveErrorCString, sizeof(resolveErrorCString), kCFStringEncodingUTF8)) {
Log("Error resolving URL: %s", resolveErrorCString);
}
CFRelease(resolveErrorString);
}
} else {
Log("Error resolving URL, no resolveError");
}
} else {
success = CFURLGetFileSystemRepresentation(photosUrl, false, photosUrlString, sizeof(photosUrlString));
CFRelease(photosUrl);
}
} else {
Log("Url plist value is not CFData");
}
if (photosUrlPrefs != NULL) {
CFRelease(photosUrlPrefs);
}
}
if(success) {
Log("path: %s", photosUrlString);
}
return 0;
}
所以,我一直在尝试反序列化 com.apple.Photos 默认值 (defaults read com.apple.Photos IPXDefaultLibraryURLBookmark
) 的 IPXDefaultLibraryURLBookmark,但没有成功。理想情况下,我希望在 C++ 中以编程方式反序列化该值以检索照片的最后已知位置
bookd0xUsersmateuscbPicturesPhotos Library.photoslibrary 0@˜ì5$r$Éò|åú¨A∫˙æJ file:///Macintosh HDÇ1tA∫‘}•65C0A4-1771-3C89-9055-147CEDFBBF2EÅÔ/∆72cd528f2dcfb4b3434986cf3caa02cc946333b8;00000000;00000000;0000000000000020;com.apple.app-sandbox.read-write;00000001;01000004;0000000002980783;/users/mateuscb/pictures/photos library.photoslibrary¥˛ˇˇˇdº‰@‘ î H ( 8 t0 †–Ä®
我知道它不是 bplist
,因为第一个格式说明符表示 bookd
。
但我不知道那是什么。我对 OSX 开发有些陌生,所以这可能是我所缺少的非常基本的东西。
我想检索:/users/mateuscb/pictures/photos library.photoslibrary
部分以便找到默认照片库。
除非有另一种方法来检索默认的照片库路径?
我想出了如何检索 .photoslibrary 的路径。我使用 CFURLCreateByResolvingBookmarkData
从 plist 中获取 CFURLRef
,然后使用 CFURLGetFileSystemRepresentation
获取字符串形式的完整路径。
通过此示例帮助检索沙盒首选项:https://gist.github.com/glebd/4759724
这是我的完整解决方案:
int main(int argc, const char * argv[]) {
bool success = FALSE;
UInt8 photosUrlString[PATH_MAX];
struct passwd *pwd = getpwuid(getuid());
if (pwd == NULL){
Log("Unable to retrieve current user");
return 0;
}
const char *home = pwd->pw_dir;
if (home == NULL){
Log("Unable to retrieve current user directory");
return 0;
}
CFMutableStringRef preferencesPath = CFStringCreateMutable(NULL, 0);
if (preferencesPath) {
CFStringAppend(preferencesPath, CFStringCreateWithCStringNoCopy(NULL, home, kCFStringEncodingUTF8, NULL));
CFStringAppend(preferencesPath, CFSTR("/Library/Containers/com.apple.Photos/Data/Library/Preferences/com.apple.Photos"));
} else {
Log("Unable to create CFString of user directory");
return 0;
}
CFPropertyListRef photosUrlPrefs = CFPreferencesCopyValue(CFSTR("IPXDefaultLibraryURLBookmark"), preferencesPath, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
CFRelease(preferencesPath);
if (photosUrlPrefs) {
CFTypeID prefsType = CFGetTypeID(photosUrlPrefs);
if (CFDataGetTypeID() == prefsType) {
CFDataRef photosUrlData = (CFDataRef) photosUrlPrefs;
CFErrorRef urlResolveError = nil;
CFURLRef photosUrl = CFURLCreateByResolvingBookmarkData(kCFAllocatorDefault, photosUrlData, NULL, NULL, NULL, NULL, &urlResolveError);
if (photosUrl == NULL) {
if(urlResolveError != NULL) {
CFStringRef resolveErrorString = CFErrorCopyDescription(urlResolveError);
if (resolveErrorString != NULL) {
char resolveErrorCString[PATH_MAX];
if (CFStringGetCString((CFStringRef) resolveErrorString, resolveErrorCString, sizeof(resolveErrorCString), kCFStringEncodingUTF8)) {
Log("Error resolving URL: %s", resolveErrorCString);
}
CFRelease(resolveErrorString);
}
} else {
Log("Error resolving URL, no resolveError");
}
} else {
success = CFURLGetFileSystemRepresentation(photosUrl, false, photosUrlString, sizeof(photosUrlString));
CFRelease(photosUrl);
}
} else {
Log("Url plist value is not CFData");
}
if (photosUrlPrefs != NULL) {
CFRelease(photosUrlPrefs);
}
}
if(success) {
Log("path: %s", photosUrlString);
}
return 0;
}