Any idea why the Mac App Store would reject based on this?

They are reporting that TaskPaper uses as private API. Here’s the exact problem they are reporting to me:

The app includes : OBJC_IVAR_$_NSATSTypesetter.paragraphGlyphRange from the framework ‘/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit’.

I have a custom subclass of NSATSTypesetter, and in that subclass I’m call self.paragraphGlyphRange four times. It’s documented as public. Does anyone know what might be causing them to reject based on this?

Note This is also odd because this code has been in since the 3.0 release, and it’s just now being flagged.

Seems like a mistake, then. Resubmit it and it’ll probably go through.

Just rejected again for third time. Before I get too mad it’s very possible that I’m doing something dumb and missing a reference or something… but boy is this frustrating!

I’m getting rejected each time for:

The use of non-public APIs can lead to a poor user experience should these APIs change in the future, and is therefore not permitted. The app still includes : OBJC_IVAR_$_NSATSTypesetter.paragraphGlyphRange from the framework ‘/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit’.

I have:

  1. Searched my code for paragraphGlyphRange. I only find it in one class.

  2. That class subclasses NSATSTypesetter which documents paragraphGlyphRange as a public property.

  3. In my subclass I have been rejected after:

    1. Making sure that all accesses to that property are done through: self.paragraphGlyphRange

    2. After doing that I still got rejected. So I changed to make all accesses through:

       [self valueForKey:@"paragraphGlyphRange"]
      

      And still rejected, same reason.

I’ve attached my mess of a subclass:

Typesetter.zip (2.0 KB)

This is really weird. We got rejected once for using private API in a typesetter – but we were actually accessing an ivar directly, versus using the getter method. Fixing that and all was okay.

I just looked into our code and while we’re not using paragraphGlyphRange, we do use paragraphCharacterRange. And funnily enough, we also convert that range into a glyph range. So maybe you try to do this instead:

NSUInteger paragraphStart = [self glyphRangeForCharacterRange:self.paragraphCharacterRange actualCharacterRange:NULL].location;

If that still does not help, I’d suggest removing the entire string “paragraphGlyphRange” from the code, replacing it with something not used in the public (and private) superclass APIs.

Hope this helps!

Ole Zorn has a theory that makes me hopeful for the next try. I initially had the same problem in my typesetter… I forgot “self.” in one part of my code, and so was accessing “paragraphGlyphRange” directly. That generated the initial IVAR error.

Then on my next submit I fixed that reference, but I had a similar problem where I forgot “self.” when accessing “layoutManager”. The reviewer sent me back the same OBJC_IVAR_$_NSATSTypesetter.paragraphGlyphRange error, but the theory is maybe they got confused when seeing another IVAR error and just pasted in the old similar error report.

Anyway, I finally learned about using nm to get relevant reports, and fixed all IVAR errors in my typesetter. Fingers crossed for next release.

I wish you all the best of luck!

1 Like

Just got approved this last time, so I’m pretty sure the theory was right. End result of what happened was:

  1. I accessed “paragraphGlyphRange” directly, causing error.
  2. Review process flagged error and reported it.
  3. I fixed it and resubmitted.
  4. In same class I accessed “layoutManager” directly, causing error.
  5. Review process flagged that… but I think because the error looked so similar they accidentally copied and pasted the previous rejection. Which unfortunately caused me lots of confusion since it was reporting that the old thing that I’d already fixed was broken.
  6. Lucky for me Ole Zorn saved me on Twitter and noticed the similar problem. Once that second case was fixed it passed review.

Phew!

4 Likes