Post

Replies

Boosts

Views

Activity

Reply to FinderSync extensions gone in macOS settings
@milke Indeed. I just wanted to add how I'm using pluginkit in an app outside the Mac App Store since Kevin made this point about pluginkit when asked if it was a valid workaround: Yes and no. A few different points to be aware of: It's certainly not something I would assume will work >"forever" and architect your app around. I use pluginkit, and have been for years for the reason I described in my previous post. It wouldn't be good for devs if they deprecated it without replacing it with something that could achieve equivalent functionality. I just wanted to put that out there in the universe. As far as my sandboxed Mac App Store Finder extensions go, there is no workaround and I'm in the same boat as everyone else. I can only explain to users how to enable the extension in Terminal or recommend the FinderSyncer app (or write my own which I do not want to spend time doing right now). Should the original answer recommending https://developer.apple.com/documentation/extensionkit/exappextensionbrowserviewcontroller?language=objc be unmarked as the Apple recommended correct answer in this thread?
Topic: App & System Services SubTopic: Core OS Tags:
Oct ’24
Reply to FinderSync extensions gone in macOS settings
I have a few Finder extension apps. None of them do any kind of syncing. All of them add actions to Finder via a custom toolbar button and/or context menu items. It's been a long time and I do remember them being introduced as "Finder Sync Extensions." At some point I thought they were renamed to "Finder Extensions." I still have a Mac running macOS Monterey and in System Preferences the section is called "Finder Extensions" not "Finder Sync Extensions." My interpretation of this was that this was an acknowledgement that these extensions may not be related to syncing (and do not necessarily have to be related to syncing). I do hope I'm not wrong about that, being that there are so many "Finder extensions" like this on the Mac App Store that were approved. Just to chime in as far as pluginkit goes, I have an outside the Mac App Store app that has been using this for years to re-enable a Finder extension after a software update (if the extension was enabled prior to updating) because a software update would cause the extension to automatically disable after the app was replaced (forcing the user to go back into Settings). So pluginkit in my case was needed to avoid customer support emails like "I updated the app and now the Finder extension is broken). PluginKit doesn't help Mac App Store / sandboxed apps though as already mentioned but hopefully pluginkit won't be removed because it still serves a purpose... Far as my Mac App Store sandboxed apps go, I had them all enabled before updating to Sequoia and they still appear and work. But new customers purchasing on Sequoia can't enable them? And existing customers that had them enabled can't disable them unless they are wizards and know how to use pluginkit from Terminal?
Topic: App & System Services SubTopic: Core OS Tags:
Oct ’24
Reply to Creating file bookmarks doesn't work anymore on macOS 15 Sequoia
Uh o. I have a sandbox app that uses security scoped bookmarks. Nobody's mentioned this to me so far. Just to throw some spaghetti at the wall, is it possible this could be related to not balancing -startAccessingSecurityScopedResource calls with -stopAccessingSecurityScopedResource when you are done with the file? If I remember from many years ago not doing this would eventually cause open/save panels etc. to no longer work in your app until after you reboot your Mac.
Topic: App & System Services SubTopic: Core OS Tags:
Sep ’24
Reply to Possible to have NSWindow *without* NSWindowStyleMaskTitled to make the screen its on the main screen?
I filed FB15237355 Is there a workaround you could recommend? I tried overriding -sendEvent: in my window subclass and passing the events to the application but none of that has made the screen active. I imagine I should be able to reroute the event when I receive it when self.screen != NSScreen.mainScreen to a code path that would trigger the screen I'm on to become the main screen
Topic: UI Frameworks SubTopic: AppKit Tags:
Sep ’24
Reply to Possible to have NSWindow *without* NSWindowStyleMaskTitled to make the screen its on the main screen?
Thank you for replying. I was having a hard time reproducing the issue in a sample project. Upon further inspection I discovered that simply using a custom shape window without a title bar is not sufficient to reproduce the issue (and may not be related to it at all). Specifying: Application is agent (UIElement) to YES in Project Settings -> Info is also required (so no dock icon) triggers this behavior. The documentation (in the archive which I believe has not been superseded) states: LSUIElement (Boolean - macOS) specifies whether the app runs as an agent app. If this key is set to YES, Launch Services runs the app as an agent app. Agent apps do not appear in the Dock or in the Force Quit window. Although they typically run as background apps, they can come to the foreground to present a user interface if desired. A click on a window belonging to an agent app brings that app forward to handle events. When the application is agent (which mine is) and the window is on a screen NOT equal to mainScreen the menu bar doesn't move over with the click. BUT if the window has a title bar (which mine doesn't because it can't, as I need the custom shape) the menu bar does travel with the click but only if you click on the title bar (if you click anywhere else on the window the screen doesn't become mainScreen).
Topic: UI Frameworks SubTopic: AppKit Tags:
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
Workaround: In New Xcode Project....delete the top level blue folder (the parent folder that contains AppDelegate.m, etc.) and all starter files. When deleting choose Remove References only. Then drag and drop the folder back into your Xcode project. Choose for Action-> Reference Files in place. Choose for Groups -> Create Groups (not folder references). Once you have a "Group Reference" you can drag and drop reorder, create new groups without folders, etc. just like you could before. Why does a new Xcode project create a folder reference in the project navigator now by default instead of a group? This must be considered a bug?
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
Okay so after going through the Xcode release notes I found this bit: "The Project Navigator now defaults to creating groups with associated folders when using the “New Group” and “New Group from Selection” commands. To create a group without a folder, hold option in the context menu to reveal the “New Group without Folder” variant of the command. (127396845)" New Group is nowhere to be found at all when there is a selection underneath an expanded blue folder in the navigator though (even if you right click on the background). You have to move the selection up to the top level to get "New Group" to show up in the context menu (and then I can hold down option key to get "New Group without Folder"). So in the case of a brand new project you have to move the selection up to the top (where you would go to edit build settings) then right click the background to get "New Group (without folder)" THEN I can create a "Supporting Files" group without a folder. However this all appears to be very buggy. After moving the .entitlements to the new group (with no folder) it still actually moves the file to the root directory next to the.xcodeproject file. In a brand new Xcode project the top level folder that contains all the starting files like the App Delegate is blue (not gray). Files cannot be reordered via drag and drop. When I right click on any file like AppDelegate.m there is no "New Group from Selection" option. There is only "New Folder from Selection". I thus cannot create a "New Group without Folder" or reorder any of the files in a starter Xcode project without actually moving the files....
Sep ’24
Reply to Mac App Store Bug Fix Updates Getting Blocked, Reviewer Sending "App Sandbox Design Guide" Broken Link
@App Review @DTS Engineer Thanks for replying. Most of the stuff in App Sandbox Design Guide was migrated to the App Sandbox area of the modern documentation. And if you want to see the old doc, I link to it in App Sandbox Resources. They kept sending me a broken link in the Resolution Center that just redirected. Thanks for sending that link. I do hope relevant information from the documentation will get moved to the new documentation. Especially information that App Review is currently using to evaluate apps, it is important for devs to have access. -- If you disagree with the outcome of our review, I don't want to sound rude but When an app has been on the store for so long (years not months) and it gets rejected for using an "unneeded entitlement"... then I explain why the entitlement is needed and the app goes back into review only to get rejected for completely different reasons with newly interpreted violations and citing references in retired documentation that is no longer accessible... it feels like App Review is trying overtime to keep my update off store. Nobody has ever complained to me about writing files in the sandbox container. I wish Apple provided sandbox apps a folder in a user-facing directory (like iCloud) but this isn't my choice. Although this app didn't get as popular as I was hoping, the app has many positive reviews. People like the app, and they ask me to fix bugs so it is very frustrating when I'm prevented from doing that. The instructions from app review are vague but I'm assuming they want me to show a save panel on launch to get to a starting point somewhere outside of my sandbox container. I'm not sure if this will make my app better. It's working by default vs. a more complicated setup process and this is a tradeoff. And I don't even know if this is exactly what App review is asking me to do. It's only what I think they want. Chasing what I think App Review wants has never worked out in my favor. It isn't going to increase my sales. It isn't clear to me that making these changes will help anyone. It certainly won't help me, having to spend a week or more designing some onboarding. And what do I do with existing users, migrate them out of the container? That's not going to be fun to implement. And maybe they don't want me to nag them in the next update to move a bunch of files around. -- To follow up: the app did go back into review and get approved which I'm thankful for. But it has a sister app with an update that's still being blocked for the same rejection reason. So it's really hard to make sense of what's going on. I think I would be less frustrated if App Review was a bit more clear as to what they want. And if they requested changes without blocking bug fixes.
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
Thanks for sharing that code. That Swift code wouldn't compile for me. I'm using Objective-C in my project but your Swift code doesn't appear like it would produce anything different than the code I'm experimenting with now (unless I'm missing something?): CGImageRef doConvertCMYKCGImageToRGB (CGImageRef sourceImage) { size_t sourceBitsPerComponent = CGImageGetBitsPerComponent(sourceImage); size_t sourceBitsPerPixel = CGImageGetBitsPerPixel(sourceImage); CGColorSpaceRef sourceColorSpace = CGImageGetColorSpace(sourceImage); CGBitmapInfo sourceBitmapInfo = CGImageGetBitmapInfo(sourceImage); CGColorRenderingIntent sourceRenderingIntent = CGImageGetRenderingIntent(sourceImage); const CGFloat *sourceDecode = CGImageGetDecode(sourceImage); vImage_CGImageFormat cmykFormat = { .bitsPerComponent = (uint32_t)sourceBitsPerComponent, // 8 .bitsPerPixel = (uint32_t)sourceBitsPerPixel, // 32 .colorSpace = sourceColorSpace, // (kCGColorSpaceICCBased; kCGColorSpaceModelCMYK; Generic CMYK Profile) .bitmapInfo = sourceBitmapInfo, // kCGBitmapByteOrderDefault .renderingIntent = sourceRenderingIntent, // kCGRenderingIntentDefault .version = 0, .decode = sourceDecode }; vImage_CGImageFormat rgbFormat = { .bitsPerComponent = 8, .bitsPerPixel = 24, .colorSpace = CGColorSpaceCreateDeviceRGB(), .bitmapInfo = (CGBitmapInfo)kCGImageAlphaNone, .renderingIntent = kCGRenderingIntentDefault }; /* Also tried: vImage_CGImageFormat rgbFormat = { .bitsPerComponent = 8, .bitsPerPixel = 32, .colorSpace = CGColorSpaceCreateDeviceRGB(), .bitmapInfo = (CGBitmapInfo)kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault, .renderingIntent = kCGRenderingIntentDefault };*/ // Initialize source buffer vImage_Buffer sourceBuffer; // You are responsible for releasing the memory pointed to by buf->data back to the system using free(). vImage_Error error = vImageBuffer_InitWithCGImage( &sourceBuffer, &cmykFormat, NULL, sourceImage, kvImageNoFlags); if (error != kvImageNoError) { os_log_error(OS_LOG_DEFAULT,"Error initializing source buffer: %ld", error); return NULL; } // Initialize destination buffer.. // You are responsible for releasing the memory pointed to by buf->data back to // the system when you are done with it using free(). If no such allocation is desired, pass // * kvImageNoAllocate in the flags to cause buf->data to be set to NULL and the preferred alignment // * to be returned from the left hand side of the function. vImage_Buffer destBuffer; error = vImageBuffer_Init(&destBuffer, sourceBuffer.height, sourceBuffer.width, rgbFormat.bitsPerPixel, kvImageNoFlags); if (error != kvImageNoError) { os_log_error(OS_LOG_DEFAULT,"Error initializing destination buffer: %ld", error); free(sourceBuffer.data); return NULL; } // Create a converter vImageConverterRef cmykToRGBConverter = vImageConverter_CreateWithCGImageFormat(&cmykFormat, &rgbFormat, NULL, kvImageNoFlags, &error); if (cmykToRGBConverter == NULL) { os_log_error(OS_LOG_DEFAULT,"Error creating vImage converter: %ld", error); free(destBuffer.data); // Free destBuffer.data. free(sourceBuffer.data); // Free sourceBuffer.data. return NULL; } // Perform the conversion error = vImageConvert_AnyToAny(cmykToRGBConverter, &sourceBuffer, &destBuffer, NULL, kvImageNoFlags); CGImageRef rgbResult = NULL; if (error == kvImageNoError) { // Create RGB result image rgbResult = vImageCreateCGImageFromBuffer(&destBuffer, &rgbFormat, NULL, NULL, kvImageNoFlags, &error); } else { os_log_error(OS_LOG_DEFAULT,"Error converting image: %ld", error); } // Create CMYK image (not needed)... //CGImageRef cmykImage = vImageCreateCGImageFromBuffer(&sourceBuffer, &cmykFormat, NULL, NULL, kvImageNoFlags, &error); // Clean up vImageConverter_Release(cmykToRGBConverter); free(destBuffer.data); // Free destBuffer.data free(sourceBuffer.data); // Free destBuffer.data return rgbResult; } Using that with image I provided in my feedback as sourceImage produces a black box (same when I pass the image data I provided in my feedback directly to higher level APIs like NSBitmapImageRep).
Topic: Graphics & Games SubTopic: General Tags:
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
I was trying all sorts of different combinations while I was hitting errors. It looks like I messed that up. Changing destination image format to use kCGImageAlphaNone like you've shown with 24 bits per pixel does in fact fix the kvImageInvalidImageFormat problem but when I convert the image I still get a black image after the conversion. I also tied changing destination format to 32 bpp with kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Host) but I still get a black CGImageRef from vImageCreateCGImageFromBuffer (though I am able to create a vImageConverter without error). Only thing I've been able to get working is iterating over the pixels and converting to RGB, then make another CGImage like so: CGContextRef context = CGBitmapContextCreate(nowRGBConvertedFromCMYK, sourceWidth, sourceHeight, sourceBitsPerCompontent, // 8 rgbBytesPerRow, rgbColorSpace, // deviceRGB kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault); // Create a new RGB image from the context CGImageRef rgbImage = CGBitmapContextCreateImage(context);
Topic: Graphics & Games SubTopic: General Tags:
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
To workaround the issue, if I iterate over the pixel data of the CMYK image I'm able to manually convert to RGB and write it into another buffer and create a CGImage with that RGB data. Then I can use CGBitmapContextCreate with the RGB buffer to generate a new image. So there appears to be an issue with how CMYK color space is being handled. Had to take a peek back in the Quartz 2D Programming Guide in the "Documentation Archive" for a refresh on some of these APIs I haven't used in a long time...
Topic: Graphics & Games SubTopic: General Tags:
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
So if I put a breakpoint right after CGImageCreateWithJPEGDataProvider and Quicklook preview sourceCGImage, the CGimageRef rendered in the Quicklook preview in the Xcode debugger is correct. But once I try to pass sourceCGImage to any higher level API it goes black. That includes NSBitmapImageRep, NSImage, CIImage, etc. I also tried creating a bitmap context and drawing the sourceCGImage in the bitmap context, but haven't been able to get that to work. Previewing the sourceCGImage right after CGImageCreateWithJPEGDataProvider from Xcode's debugger when I hit that breakpoint is the only time the image is rendered correctly. I wonder what API is being used to render the CGImage from the Xcode debugger?
Topic: Graphics & Games SubTopic: General Tags:
Sep ’24
Reply to FinderSync extensions gone in macOS settings
@milke Indeed. I just wanted to add how I'm using pluginkit in an app outside the Mac App Store since Kevin made this point about pluginkit when asked if it was a valid workaround: Yes and no. A few different points to be aware of: It's certainly not something I would assume will work >"forever" and architect your app around. I use pluginkit, and have been for years for the reason I described in my previous post. It wouldn't be good for devs if they deprecated it without replacing it with something that could achieve equivalent functionality. I just wanted to put that out there in the universe. As far as my sandboxed Mac App Store Finder extensions go, there is no workaround and I'm in the same boat as everyone else. I can only explain to users how to enable the extension in Terminal or recommend the FinderSyncer app (or write my own which I do not want to spend time doing right now). Should the original answer recommending https://developer.apple.com/documentation/extensionkit/exappextensionbrowserviewcontroller?language=objc be unmarked as the Apple recommended correct answer in this thread?
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Oct ’24
Reply to FinderSync extensions gone in macOS settings
I have a few Finder extension apps. None of them do any kind of syncing. All of them add actions to Finder via a custom toolbar button and/or context menu items. It's been a long time and I do remember them being introduced as "Finder Sync Extensions." At some point I thought they were renamed to "Finder Extensions." I still have a Mac running macOS Monterey and in System Preferences the section is called "Finder Extensions" not "Finder Sync Extensions." My interpretation of this was that this was an acknowledgement that these extensions may not be related to syncing (and do not necessarily have to be related to syncing). I do hope I'm not wrong about that, being that there are so many "Finder extensions" like this on the Mac App Store that were approved. Just to chime in as far as pluginkit goes, I have an outside the Mac App Store app that has been using this for years to re-enable a Finder extension after a software update (if the extension was enabled prior to updating) because a software update would cause the extension to automatically disable after the app was replaced (forcing the user to go back into Settings). So pluginkit in my case was needed to avoid customer support emails like "I updated the app and now the Finder extension is broken). PluginKit doesn't help Mac App Store / sandboxed apps though as already mentioned but hopefully pluginkit won't be removed because it still serves a purpose... Far as my Mac App Store sandboxed apps go, I had them all enabled before updating to Sequoia and they still appear and work. But new customers purchasing on Sequoia can't enable them? And existing customers that had them enabled can't disable them unless they are wizards and know how to use pluginkit from Terminal?
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Oct ’24
Reply to Creating file bookmarks doesn't work anymore on macOS 15 Sequoia
Uh o. I have a sandbox app that uses security scoped bookmarks. Nobody's mentioned this to me so far. Just to throw some spaghetti at the wall, is it possible this could be related to not balancing -startAccessingSecurityScopedResource calls with -stopAccessingSecurityScopedResource when you are done with the file? If I remember from many years ago not doing this would eventually cause open/save panels etc. to no longer work in your app until after you reboot your Mac.
Topic: App & System Services SubTopic: Core OS Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to Possible to have NSWindow *without* NSWindowStyleMaskTitled to make the screen its on the main screen?
I filed FB15237355 Is there a workaround you could recommend? I tried overriding -sendEvent: in my window subclass and passing the events to the application but none of that has made the screen active. I imagine I should be able to reroute the event when I receive it when self.screen != NSScreen.mainScreen to a code path that would trigger the screen I'm on to become the main screen
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to Possible to have NSWindow *without* NSWindowStyleMaskTitled to make the screen its on the main screen?
Thank you for replying. I was having a hard time reproducing the issue in a sample project. Upon further inspection I discovered that simply using a custom shape window without a title bar is not sufficient to reproduce the issue (and may not be related to it at all). Specifying: Application is agent (UIElement) to YES in Project Settings -> Info is also required (so no dock icon) triggers this behavior. The documentation (in the archive which I believe has not been superseded) states: LSUIElement (Boolean - macOS) specifies whether the app runs as an agent app. If this key is set to YES, Launch Services runs the app as an agent app. Agent apps do not appear in the Dock or in the Force Quit window. Although they typically run as background apps, they can come to the foreground to present a user interface if desired. A click on a window belonging to an agent app brings that app forward to handle events. When the application is agent (which mine is) and the window is on a screen NOT equal to mainScreen the menu bar doesn't move over with the click. BUT if the window has a title bar (which mine doesn't because it can't, as I need the custom shape) the menu bar does travel with the click but only if you click on the title bar (if you click anywhere else on the window the screen doesn't become mainScreen).
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
Workaround: In New Xcode Project....delete the top level blue folder (the parent folder that contains AppDelegate.m, etc.) and all starter files. When deleting choose Remove References only. Then drag and drop the folder back into your Xcode project. Choose for Action-> Reference Files in place. Choose for Groups -> Create Groups (not folder references). Once you have a "Group Reference" you can drag and drop reorder, create new groups without folders, etc. just like you could before. Why does a new Xcode project create a folder reference in the project navigator now by default instead of a group? This must be considered a bug?
Replies
Boosts
Views
Activity
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
Okay so after going through the Xcode release notes I found this bit: "The Project Navigator now defaults to creating groups with associated folders when using the “New Group” and “New Group from Selection” commands. To create a group without a folder, hold option in the context menu to reveal the “New Group without Folder” variant of the command. (127396845)" New Group is nowhere to be found at all when there is a selection underneath an expanded blue folder in the navigator though (even if you right click on the background). You have to move the selection up to the top level to get "New Group" to show up in the context menu (and then I can hold down option key to get "New Group without Folder"). So in the case of a brand new project you have to move the selection up to the top (where you would go to edit build settings) then right click the background to get "New Group (without folder)" THEN I can create a "Supporting Files" group without a folder. However this all appears to be very buggy. After moving the .entitlements to the new group (with no folder) it still actually moves the file to the root directory next to the.xcodeproject file. In a brand new Xcode project the top level folder that contains all the starting files like the App Delegate is blue (not gray). Files cannot be reordered via drag and drop. When I right click on any file like AppDelegate.m there is no "New Group from Selection" option. There is only "New Folder from Selection". I thus cannot create a "New Group without Folder" or reorder any of the files in a starter Xcode project without actually moving the files....
Replies
Boosts
Views
Activity
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
FB15209556
Replies
Boosts
Views
Activity
Sep ’24
Reply to Project Navigator Broken in Xcode 16? Drag and Drop to Reorder Files Doesn't Work. "New Groups" Creates New Folders.
FB15195096
Replies
Boosts
Views
Activity
Sep ’24
Reply to Mac App Store Bug Fix Updates Getting Blocked, Reviewer Sending "App Sandbox Design Guide" Broken Link
@App Review @DTS Engineer Thanks for replying. Most of the stuff in App Sandbox Design Guide was migrated to the App Sandbox area of the modern documentation. And if you want to see the old doc, I link to it in App Sandbox Resources. They kept sending me a broken link in the Resolution Center that just redirected. Thanks for sending that link. I do hope relevant information from the documentation will get moved to the new documentation. Especially information that App Review is currently using to evaluate apps, it is important for devs to have access. -- If you disagree with the outcome of our review, I don't want to sound rude but When an app has been on the store for so long (years not months) and it gets rejected for using an "unneeded entitlement"... then I explain why the entitlement is needed and the app goes back into review only to get rejected for completely different reasons with newly interpreted violations and citing references in retired documentation that is no longer accessible... it feels like App Review is trying overtime to keep my update off store. Nobody has ever complained to me about writing files in the sandbox container. I wish Apple provided sandbox apps a folder in a user-facing directory (like iCloud) but this isn't my choice. Although this app didn't get as popular as I was hoping, the app has many positive reviews. People like the app, and they ask me to fix bugs so it is very frustrating when I'm prevented from doing that. The instructions from app review are vague but I'm assuming they want me to show a save panel on launch to get to a starting point somewhere outside of my sandbox container. I'm not sure if this will make my app better. It's working by default vs. a more complicated setup process and this is a tradeoff. And I don't even know if this is exactly what App review is asking me to do. It's only what I think they want. Chasing what I think App Review wants has never worked out in my favor. It isn't going to increase my sales. It isn't clear to me that making these changes will help anyone. It certainly won't help me, having to spend a week or more designing some onboarding. And what do I do with existing users, migrate them out of the container? That's not going to be fun to implement. And maybe they don't want me to nag them in the next update to move a bunch of files around. -- To follow up: the app did go back into review and get approved which I'm thankful for. But it has a sister app with an update that's still being blocked for the same rejection reason. So it's really hard to make sense of what's going on. I think I would be less frustrated if App Review was a bit more clear as to what they want. And if they requested changes without blocking bug fixes.
Replies
Boosts
Views
Activity
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
1.000000 0.000000, 1.000000, 0.000000, 1.000000, 0.000000, 1.000000, 0.000000 -- I did try passing in NULL but still end up with a black box.
Topic: Graphics & Games SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
Thanks for sharing that code. That Swift code wouldn't compile for me. I'm using Objective-C in my project but your Swift code doesn't appear like it would produce anything different than the code I'm experimenting with now (unless I'm missing something?): CGImageRef doConvertCMYKCGImageToRGB (CGImageRef sourceImage) { size_t sourceBitsPerComponent = CGImageGetBitsPerComponent(sourceImage); size_t sourceBitsPerPixel = CGImageGetBitsPerPixel(sourceImage); CGColorSpaceRef sourceColorSpace = CGImageGetColorSpace(sourceImage); CGBitmapInfo sourceBitmapInfo = CGImageGetBitmapInfo(sourceImage); CGColorRenderingIntent sourceRenderingIntent = CGImageGetRenderingIntent(sourceImage); const CGFloat *sourceDecode = CGImageGetDecode(sourceImage); vImage_CGImageFormat cmykFormat = { .bitsPerComponent = (uint32_t)sourceBitsPerComponent, // 8 .bitsPerPixel = (uint32_t)sourceBitsPerPixel, // 32 .colorSpace = sourceColorSpace, // (kCGColorSpaceICCBased; kCGColorSpaceModelCMYK; Generic CMYK Profile) .bitmapInfo = sourceBitmapInfo, // kCGBitmapByteOrderDefault .renderingIntent = sourceRenderingIntent, // kCGRenderingIntentDefault .version = 0, .decode = sourceDecode }; vImage_CGImageFormat rgbFormat = { .bitsPerComponent = 8, .bitsPerPixel = 24, .colorSpace = CGColorSpaceCreateDeviceRGB(), .bitmapInfo = (CGBitmapInfo)kCGImageAlphaNone, .renderingIntent = kCGRenderingIntentDefault }; /* Also tried: vImage_CGImageFormat rgbFormat = { .bitsPerComponent = 8, .bitsPerPixel = 32, .colorSpace = CGColorSpaceCreateDeviceRGB(), .bitmapInfo = (CGBitmapInfo)kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault, .renderingIntent = kCGRenderingIntentDefault };*/ // Initialize source buffer vImage_Buffer sourceBuffer; // You are responsible for releasing the memory pointed to by buf->data back to the system using free(). vImage_Error error = vImageBuffer_InitWithCGImage( &sourceBuffer, &cmykFormat, NULL, sourceImage, kvImageNoFlags); if (error != kvImageNoError) { os_log_error(OS_LOG_DEFAULT,"Error initializing source buffer: %ld", error); return NULL; } // Initialize destination buffer.. // You are responsible for releasing the memory pointed to by buf->data back to // the system when you are done with it using free(). If no such allocation is desired, pass // * kvImageNoAllocate in the flags to cause buf->data to be set to NULL and the preferred alignment // * to be returned from the left hand side of the function. vImage_Buffer destBuffer; error = vImageBuffer_Init(&destBuffer, sourceBuffer.height, sourceBuffer.width, rgbFormat.bitsPerPixel, kvImageNoFlags); if (error != kvImageNoError) { os_log_error(OS_LOG_DEFAULT,"Error initializing destination buffer: %ld", error); free(sourceBuffer.data); return NULL; } // Create a converter vImageConverterRef cmykToRGBConverter = vImageConverter_CreateWithCGImageFormat(&cmykFormat, &rgbFormat, NULL, kvImageNoFlags, &error); if (cmykToRGBConverter == NULL) { os_log_error(OS_LOG_DEFAULT,"Error creating vImage converter: %ld", error); free(destBuffer.data); // Free destBuffer.data. free(sourceBuffer.data); // Free sourceBuffer.data. return NULL; } // Perform the conversion error = vImageConvert_AnyToAny(cmykToRGBConverter, &sourceBuffer, &destBuffer, NULL, kvImageNoFlags); CGImageRef rgbResult = NULL; if (error == kvImageNoError) { // Create RGB result image rgbResult = vImageCreateCGImageFromBuffer(&destBuffer, &rgbFormat, NULL, NULL, kvImageNoFlags, &error); } else { os_log_error(OS_LOG_DEFAULT,"Error converting image: %ld", error); } // Create CMYK image (not needed)... //CGImageRef cmykImage = vImageCreateCGImageFromBuffer(&sourceBuffer, &cmykFormat, NULL, NULL, kvImageNoFlags, &error); // Clean up vImageConverter_Release(cmykToRGBConverter); free(destBuffer.data); // Free destBuffer.data free(sourceBuffer.data); // Free destBuffer.data return rgbResult; } Using that with image I provided in my feedback as sourceImage produces a black box (same when I pass the image data I provided in my feedback directly to higher level APIs like NSBitmapImageRep).
Topic: Graphics & Games SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
I was trying all sorts of different combinations while I was hitting errors. It looks like I messed that up. Changing destination image format to use kCGImageAlphaNone like you've shown with 24 bits per pixel does in fact fix the kvImageInvalidImageFormat problem but when I convert the image I still get a black image after the conversion. I also tied changing destination format to 32 bpp with kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Host) but I still get a black CGImageRef from vImageCreateCGImageFromBuffer (though I am able to create a vImageConverter without error). Only thing I've been able to get working is iterating over the pixels and converting to RGB, then make another CGImage like so: CGContextRef context = CGBitmapContextCreate(nowRGBConvertedFromCMYK, sourceWidth, sourceHeight, sourceBitsPerCompontent, // 8 rgbBytesPerRow, rgbColorSpace, // deviceRGB kCGImageAlphaNoneSkipLast | kCGBitmapByteOrderDefault); // Create a new RGB image from the context CGImageRef rgbImage = CGBitmapContextCreateImage(context);
Topic: Graphics & Games SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
To workaround the issue, if I iterate over the pixel data of the CMYK image I'm able to manually convert to RGB and write it into another buffer and create a CGImage with that RGB data. Then I can use CGBitmapContextCreate with the RGB buffer to generate a new image. So there appears to be an issue with how CMYK color space is being handled. Had to take a peek back in the Quartz 2D Programming Guide in the "Documentation Archive" for a refresh on some of these APIs I haven't used in a long time...
Topic: Graphics & Games SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’24
Reply to vImageConverter_CreateWithCGImageFormat Fails with kvImageInvalidImageFormat When Trying to Convert CMYK to RGB
So if I put a breakpoint right after CGImageCreateWithJPEGDataProvider and Quicklook preview sourceCGImage, the CGimageRef rendered in the Quicklook preview in the Xcode debugger is correct. But once I try to pass sourceCGImage to any higher level API it goes black. That includes NSBitmapImageRep, NSImage, CIImage, etc. I also tried creating a bitmap context and drawing the sourceCGImage in the bitmap context, but haven't been able to get that to work. Previewing the sourceCGImage right after CGImageCreateWithJPEGDataProvider from Xcode's debugger when I hit that breakpoint is the only time the image is rendered correctly. I wonder what API is being used to render the CGImage from the Xcode debugger?
Topic: Graphics & Games SubTopic: General Tags:
Replies
Boosts
Views
Activity
Sep ’24