meaning of - Apps that use non-public APIs will be rejected - ios

our app have been rejected by iTunes because of using non-public APIs
We found that your app uses one or more non-public APIs, which is not in compliance with the App Store Review Guidelines. The use of non-public APIs is not permissible because it can lead to a poor user experience should these APIs change.
We found the following non-public API/s in your app:
.......
If you have defined methods in your source code with the same names as the above-mentioned APIs, we suggest altering your method names so that they no longer collide with Apple's private APIs to avoid your application being flagged in future submissions.
what is the meaning of that rejection?
does it means:there are some apple interface "SomeAppleInterface"
// SomeAppleInterface.m
#implementation SomeAppleInterface
- (void)SomePrivateAPI // this api doesn't exists in SomeAppleInterface.h file
{
// ... some code
}
and in my code i call to a private api of apple class:
- (void)MyCodeMethod
{
SomeAppleInterface x;
[x SomePrivateAPI];
}
is it the meaning of this error? if yes how could i call to this private method, it is not mentioned in h file?
please help me to understand

You are asking for clarification for a rejection that is, most likely, simply an error on Apple's part. This list looks like a bunch of false positives. All they're saying is that you appear be calling a bunch of methods that they believe to be part of the private API.
In this question, you provide a straw man, showing us an invocation of a private method which will not compile. You seem to be asking "how could I have accidentally called the Apple private API?"
The thing is, it's really hard to accidentally call the private API. You'd could create a category #interface that exposed the private API. There are other ways, too, but this simply isn't something you can accidentally do. You have to consciously take steps to call a private API.
So the question becomes how one could get a false positive report from Apple. It's possible that you're not using Apple's private API at all, but happen to have methods in your own classes with the same signature. This might result in a false positive which can be resolved by simply changing the name of your method.
But in this case, I think there is something completely different going on and I don't think it's worth trying to track it down until you hear back from Apple. There's no point in getting all lathered up about it until you hear back from them.

Related

Can I make a background data fetch in an external library?

I am currently making a SDK that would require fetching data in the background. For an example, let's say that the SDK provides some weather data that needs to be relatively fresh to be useful. At some point, the data is outdated and needs to be refreshed. The problem is, that the app might be often used in places with poor internet connection, or with no internet access at all. This brings me to the idea that maybe I should fetch the data in background, when the internet is accessible.
The SDK is packaged into a XCFramework, and distributed using Swift Package Manager. When I try adding capabilities to my target, Xcodes gives me a screen that states "No matches, Capabilities are not supported for SDK".
Is it even possible to make a background data fetch without the access to app capabilities? Or does this responsibility fall to the client app for my SDK? Sorry if the answer is obvious, I've tried searching online for a direct response to my problem, and wasn't able to find a clear answer.
An SDK/framework can't request such capabilities, but it can contain the code necessary to do all the work. You need to expose a function that the client can call to run this code.
E.g.
Inside your framework
public func setupBackgroundDataFetching() {
// create background task
}
Then inside your README, you need to tell users that they have to enable this capability and call:
let weatherSDK = WeatherSDK()
weatherSDK.setupBackgroundDataFetching()
Inside their AppDelegate. Depending on your use case you may need to have the function take in some parameters, or make a singleton class and have this as a static/class func, etc. But the basic idea is the same, wrap up the code and ask the client to invoke it
Example:
Heres the repo of a crash reporting tool I use: https://github.com/getsentry/sentry-cocoa
You'll notice their README contains installation/usage guide which asks users to run a setup method in their AppDelegate, which takes in a configuration. Based on this configuration, they can setup anything they need once the app starts, such as a background task if needed

AppStore rejected: use of private calls refers to my own methods

I received the following rejection message:
Your app uses or references the following non-public APIs:
removeItems:,
setSelectedSection:
setIsNew:
selectedSection
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.
Looking through the code, I find removeItems: in a piece of code implemented by Xcode Core Data code generator (I have a substructure called items).
selectedSection and isNew are property in generated core data code.
The code passed last deployment. And the code passed beta review two or three weeks ago.
Does Apple forbid to use these function names in MY private code? Or is there currently an AppStore issue with false positives?
UPDATE: I received the following answer from Apple App Review team:
Thank you for your response. For each of the selectors at issue, we
found the following occurrences:
... 4 method uses deleted ...
To clarify, these are not necessarily direct uses of non-public APIs,
but as your app does not have these statically defined, they are name
collisions with possible private selectors, and as such revision is
appropriate.
The last section is especially interesting: Does this mean, that I cannot any longer choose the names of any methods free of fear that Apple might come up with the same method name? Or, to reduce it to a objc question: what is "statically defined"? static C-methods? class-methods?
The reason for rejection is actually really that I am using selectors that Apple decided to make introduce as private selectors.
This can happen at any time, with any version and there is no testing facility but the app review (at the time of this writing).
It seems that Apple changed policy here, earlier, they just send out a warning, nowadays the app is refused.
The solution is actually simple, but can require major efforts.
rename the selectors listed in the review report
rename properties, also dynamic properties from core-data, that match the report. In my case, all reported fields were core-data properties. This required renaming of database fields and thus I had to add a new DB schema version and rename the fields accordingly and initialize the db stack with auto-migration enabled.

Mangopay implementation for zf2

I'm looking for a vendor/module that implements mangopay functionality into zf2.
Has anyone done this before or know someone who can do it?
I espially need e-wallet and adaptive payment functionality.
My team and I used https://github.com/MangoPay/mangopay2-php-sdk with success on a ZF2 project (I don't know if I can name it here without being perceived as advertisement and/or url bombing, but you can contact me for further details).
Pro tips:
Do not use the library directly in your business code, always wrap calls to this API into a dedicated service. Create a Wallet service with business-related methods (public function createUser(User $user), public function createCardRegistration(User $user, Card $creditCard), ...)
Be careful to properly read MangoPay api reference (https://docs.mangopay.com/api-references/) before you begin to use any feature, every detail is important and a missed sentence can rapidly become a headache
Don't be afraid to contact the support team (https://www.mangopay.com/contact/ with a technical case type) when you're blocked. They're fast and can unlock an apparently blocked situation in minutes.
Log everything, too much log is better than no log when it comes to payment. Play with log levels if you can't handle this much log :)

How to differenciate between Public vs Undocumented / Private API in iOS programmatically?

Is their a safe way to determine if class / method you are accessing is not restricted at runtime ?
Or
do these classes have some property which you check and safely avoid using them?
E.g. UINavigationTransitionView or UITransitionView are accessible but undocumented, hence I assume you are not allowed to use them.
Uhm, as the name implies, any method or class not documented in the public Apple documentation or in the SDK header files is considered private API and should not be used for AppStore submissions.
Note, that sometimes you may find yourself accessing public methods on private classes. This is generally acceptable, but it depends on your use.
There are also cases, where Apple has opened API and made public retroactively, meaning you can use a method for current SDK as well as call it on previous versions of iOS safely. Examples of this include NSArray's firstObject and NSDatas base64 API.
There's no way to check programmatically at run-time. In order to know whether you're accessing a private API, you'd need to know which SDK the app was built with, and then you'd need to check every function or method call against the headers from that SDK. Since iPhones don't generally have an SDK installed, there's no way to do that check at runtime.
If you use constructions like:
Class transitionViewClass = NSClassFromString("UITransitionView");
then it's impossible to determine it's access level (public or private) at runtime.
It's better to use direct access to classes/methods:
Class transitionViewClass = [UITransitionView class];
In this case compiler that Xcode uses will show warnings/errors that this class is undeclared:
Semantic issue: Use of undeclared identifier 'UITransitionView'

How do I access the source level definition of classes at runtime?

How do I access the Objective-C class interface defanition that is collected from headers at (pre or actual) compile time so I can provide introspection that is true to the defined public interface.
Problem: F-Script, SuperDB, IKBClassBrowser, CBIntrospection use the class_copyPropertyList() family of functions to introspect objects at run time. While powerful, there are drawbacks…
the runtime has no concept of private and public… everything is
returned
I can not see a reliable way to access the to the ObjC types of
method arguments and returns
Goal: I am researching a iOS app to help teach coding via a live / immediate development environment (similar to SmallTalk, F-Script, SuperDB, IKBClassBrowser, CBIntrospection). I want users to introspect objects, send messages, create new objects, and build and run code via a VM. But I want to limit the functionality to public functions (there is no way Apple would approve the app otherwise) and I want to have access to types so I limit so users can only pass legal objects.
My hope is that there is some way to access Clang or the symbol file to pull this information in way I can use it at runtime. It does not have to be fully automated (I will probably want to limit functionality in some ways)
You're encountering one of the distinguishing characteristics of Objective-C: There is no such thing as private or public API. There's only documented API vs. undocumented API. You can call any method on any object at any time, regardless of whether it appears in a header file. Public/private distinctions exist only for the compiler; at run time, they don't exist, and there's no way to reverse the process and discern what the header files might have said.

Resources