Recent

Author Topic: CGDisplayBitsPerPixel not a public API - App Store issue  (Read 2432 times)

CCRDude

  • Sr. Member
  • ****
  • Posts: 492
CGDisplayBitsPerPixel not a public API - App Store issue
« on: February 27, 2019, 09:48:02 am »
I've got my first app in the app store for a few month now, and it has custom BGRA based graphics adjusted to the screen resolution.

I just got a message from Apple:

Quote
Found private symbol usage.
Symbol: _CGDisplayBitsPerPixel
From framework: /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
In binary: Contents/MacOS/Spybot3IdentityMonitor64

We are constantly reevaluating and identifying non-public APIs that you may have been using for an extended period of time. You should always use public APIs and frameworks and ensure they are up-to-date to prevent this issue in the future.

The use of non-public APIs is not permitted on the App Store, because it can lead to a poor user experience should these APIs change.

CGDisplayBitsPerPixel is documented as deprecated, and CGDisplayModeCopyPixelEncoding suggested instead. On this page, that function is listed as deprecated as well.

It's used in:
  • lcl/interfaces/carbon/carbonwinapi.inc
  • lcl/interfaces/cocoa/cocoawinapi.inc
  • packages/graph/src/macosx/graph.pp
I assume I'm affected since my app is Cocoa, that's why I'm posting here. I'm not really fit enough in MacOS APIs yet to properly implement a new version I'm afraid   :-[
« Last Edit: March 15, 2019, 08:53:43 am by CCRDude »

VTwin

  • Hero Member
  • *****
  • Posts: 738
  • Former Turbo Pascal 3 user
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #1 on: March 06, 2019, 02:12:39 am »
Wow.  :o Congratulations on the App Store acceptance. I'm not in a position to help, but I find it a bit creepy that they are poking around looking for "non-public APIs". I'm not clear what they mean, non-Apple I guess.

I maintain several fairly widely used applications on Mac, Windows, and Linux, and am increasingly alarmed at Apple's ratcheting down. In their past they famously relied on "hackers" and small developers. They do not accept GPL software either. I am currently converting my software to GPL, so presumably will never make it into the App Sore.
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.11.6: Lazarus 2.1.0 svn 61673M (64 bit Cocoa trunk)
Ubuntu 18.04.3: Lazarus 2.0.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.4 (64 bit on VBox)

PascalDragon

  • Hero Member
  • *****
  • Posts: 505
  • Compiler Developer
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #2 on: March 06, 2019, 09:27:37 am »
Wow.  :o Congratulations on the App Store acceptance. I'm not in a position to help, but I find it a bit creepy that they are poking around looking for "non-public APIs". I'm not clear what they mean, non-Apple I guess.
Why do you think that's creepy? They only need to check what symbols are imported by the binary and that can be compared to a white or black list which can (and will) be done automatically.
I don't know about Apple, but Microsoft even provides a tool that you can use to check your app for validity with the store regarding unsupported APIs.

I can also understand their intention: if you use unsupported, non-public APIs then things can essentially go two ways:
- Apple/Microsoft decides to drop or change the non-public function and now your app no longer works (or no longer works correctly if the change is subtle enough)
- Apple/Microsoft keeps supporting the non-public function, because apps now depend on it.

It's rather well known that Apple usually goes the first route while Microsoft goes the latter (they even kept supporting a functionality that was only used in the *beta* of - I think - Windows 95 by four programs). While one could criticize Apple for their way the one from Microsoft is not hassle free either, especially if programs rely on buggy behaviour for which Microsoft introduced their shim system that transparently loads "buggy" versions of their APIs for programs that need them while those that don't rely on some bug get the normal version.

VTwin

  • Hero Member
  • *****
  • Posts: 738
  • Former Turbo Pascal 3 user
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #3 on: March 06, 2019, 03:18:07 pm »
Fair enough PascalDragon. I actually do get it. Just letting some steam off being frustrated trying to keep up with Apple's changes. For me, the App Store fees and non-support for GPL are a non-starter. However, I don't have to make a living with my software. 

Wouldn't it be nice, in my fantasy world, if Apple offered one programmer to help tidy up any loose ends in Lazarus's Cocoa widget set? :)
« Last Edit: March 06, 2019, 03:25:31 pm by VTwin »
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.11.6: Lazarus 2.1.0 svn 61673M (64 bit Cocoa trunk)
Ubuntu 18.04.3: Lazarus 2.0.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.4 (64 bit on VBox)

CCRDude

  • Sr. Member
  • ****
  • Posts: 492
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #4 on: March 12, 2019, 09:24:44 am »
I even got a call by an Apple representative talking to me to make sure I would understand the issue they have. Without mentioning the reason why this specific API call is deprecated, following what sounded like a standard script on such issues - but that they would call to make sure there's an understanding is nice.

The issue of looking for deprecated functions isn't such a big one imho. I wrote a tool (CompatAlyzer) for the other route many years ago - the import table is well-defined in ELF (in my case back then PE) format and only needs to be compared to list of functions supported by an OS. Back then, I used this to identify which new Delphi functions were responsible for programs no longer running on Windows 95 and fixing the Delphi RTL accordingly. I don't like the "force", but reminding developers about issues to make sure programs are compatible to future OS versions is a good thing imho.

As soon as I've find a bit of free time, I'll test the alternatives to CGDisplayBitsPerPixel.

CCRDude

  • Sr. Member
  • ****
  • Posts: 492
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #5 on: March 14, 2019, 10:46:09 am »
Here's my first replacement code on this issue:

Code: [Select]
const
  // https://opensource.apple.com/source/IOGraphics/IOGraphics-406/IOGraphicsFamily/IOKit/graphics/IOGraphicsTypes.h.auto.html
  IO1BitIndexedPixels = 'P';
  IO2BitIndexedPixels = 'PP';
  IO4BitIndexedPixels = 'PPPP';
  IO8BitIndexedPixels = 'PPPPPPPP';
  IO16BitDirectPixels = '-RRRRRGGGGGBBBBB';
  IO32BitDirectPixels = '--------RRRRRRRRGGGGGGGGBBBBBBBB';
  kIO30BitDirectPixels = '--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB';
  kIO64BitDirectPixels = '-16R16G16B16';
  kIO16BitFloatPixels = '-16FR16FG16FB16';
  kIO32BitFloatPixels = '-32FR32FG32FB32';
  IOYUV422Pixels = 'Y4U2V2';
  IO8BitOverlayPixels = 'O8';

function MacOSGetDisplayBitsPerPixel(ADefault: integer): integer;
var
  mode: CGDisplayModeRef;
  r: CFStringRef;
  rString: shortstring;
begin
  Result := ADefault;
  // CGDisplayModeCopyPixelEncoding is the alternative recommended by the
  // CGDisplayBitsPerPixel Apple Developer website page.
  // https://developer.apple.com/documentation/coregraphics/1455067-cgdisplaymodecopypixelencoding?language=objc
  // It is listed as deprecated on this overview page:
  // https://developer.apple.com/documentation/coregraphics/quartz_display_services?language=objc#1656418
  mode := CGDisplayCopyDisplayMode(CGMainDisplayID);
  try
    r := CGDisplayModeCopyPixelEncoding(mode);
    try
      CFStringGetPascalString(r, @rString, 255, CFStringGetSystemEncoding());
      case rString of
        IO1BitIndexedPixels: Result := 1;
        IO2BitIndexedPixels: Result := 2;
        IO4BitIndexedPixels: Result := 4;
        IO8BitIndexedPixels: Result := 8;
        IO16BitDirectPixels: Result := 16;
        IO32BitDirectPixels: Result := 32;
        kIO30BitDirectPixels: Result := 30;
        kIO64BitDirectPixels: Result := 64;
        kIO16BitFloatPixels: Result := 16;
        kIO32BitFloatPixels: Result := 32;
        IOYUV422Pixels: Result := 6;
        IO8BitOverlayPixels: Result := 8;
      end;
    finally
      // FreeCFString(r);
    end;
  finally
    CFRelease(mode);
  end;
end;

This can probably be optimized, since CGDisplayModeCopyPixelEncoding might already be deprecated as well...

VTwin

  • Hero Member
  • *****
  • Posts: 738
  • Former Turbo Pascal 3 user
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #6 on: March 15, 2019, 12:00:51 am »
I don't like the "force", but reminding developers about issues to make sure programs are compatible to future OS versions is a good thing imho.

It seems they are being proactive and positive in helping small developers then. I'm very pleased to hear that.
“Talk is cheap. Show me the code.” -Linus Torvalds

macOS 10.11.6: Lazarus 2.1.0 svn 61673M (64 bit Cocoa trunk)
Ubuntu 18.04.3: Lazarus 2.0.4 (64 bit on VBox)
Windows 7 Pro SP1: Lazarus 2.0.4 (64 bit on VBox)

CCRDude

  • Sr. Member
  • ****
  • Posts: 492
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #7 on: April 25, 2019, 07:51:41 am »
It's been five weeks this issue has been escalated at Apple, without any further response from them.

All the positive attitude seen in this approach is gone on my side :(

I hope this call is not part of every Lazarus app.

CCRDude

  • Sr. Member
  • ****
  • Posts: 492
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #8 on: May 27, 2019, 10:24:54 am »
Another month this has been idle as a paid Technical Support Incident. No answers that arrived via email or that I could find online.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2234
    • havefunsoft.com
Re: CGDisplayBitsPerPixel not a public API - App Store issue
« Reply #9 on: May 27, 2019, 06:42:10 pm »
We are constantly reevaluating and identifying non-public APIs that you may have been using for an extended period of time. You should always use public APIs and frameworks and ensure they are up-to-date to prevent this issue in the future.
You really should've reported it as Cocoa WS bug.
Cocoa WS is not designed to be a hobbyist project, but is expected to work for "app store" (commercial) applications.

r61296 removes the use of CGDisplayBitsPerPixel function. Replacing it with the corresponding NSScreen use.

I'm not posting any apps to the AppStore, thus Cocoa WS hardly depends on the developers using both (AppStore and LCL) to report such deprecations.

Those "deprecations" might occur, because a lot of parts (specifically on the graphics sides) have been copied over from Carbon.
« Last Edit: May 27, 2019, 06:45:12 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz