I am using some non-public method to better control the slide effects of my application, for example:
[self dismissModalViewControllerWithTransition:2];
After trying to upload my App with the Application Loader I got the message that I can not use such non-public methods. I found in stackoverflow a nice workaround here: How does Apple know you are using private API?
So, I've adapted my code:
int tvalue = 2;
objc_msgSend(self, sel_getUid("dismissModalViewControllerWithTransition:"), tvalue);
After changing the code, the Application Loader did accept my binary. So here my question: can I get any problems when the App gets revised by apple?
Thanks in advance.
You cannot. Your app was not rejected because Apple could not track properly your code. Skip using non-public methods.
Related
my app was rejected by Apple, because somehow my app uses private API's.
Apple said that my app uses
framework: '/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation': CFHashBytes
I couldn't find anything in the code, so I searched stackoverflow and fout out that I can use otool or strings.
With string I find two "hash" calls (wherever they are) and using nm, I get the following output:
nm Sporty\ Architect | grep hash
0000000100077490 T __TFO16Sporty_Architect12ActivityTypeg9hashValueSi
0000000100056240 T __TFO16Sporty_Architect12RotationModeg9hashValueSi
0000000100064480 T __TFO16Sporty_Architect13DraggedSliderg9hashValueSi
000000010003e3a0 T __TFO16Sporty_Architect8FileTypeg9hashValueSi
000000010003d910 T __TFO16Sporty_Architect9DateRangeg9hashValueSi
0000000100021360 T __TFO16Sporty_Architect9ModelModeg9hashValueSi
U __TFSig9hashValueSi
00000001000777b0 T __TTWO16Sporty_Architect12ActivityTypes8HashableS_FS1_g9hashValueSi
00000001000562e0 T __TTWO16Sporty_Architect12RotationModes8HashableS_FS1_g9hashValueSi
0000000100064500 T __TTWO16Sporty_Architect13DraggedSliders8HashableS_FS1_g9hashValueSi
000000010003e9d0 T __TTWO16Sporty_Architect8FileTypes8HashableS_FS1_g9hashValueSi
000000010003e080 T __TTWO16Sporty_Architect9DateRanges8HashableS_FS1_g9hashValueSi
0000000100021500 T __TTWO16Sporty_Architect9ModelModes8HashableS_FS1_g9hashValueSi
I think the U __TFSig9hashValueSi is it, isn't it? But now the question...how can i narrow this down any further?
It is beyond me, why Apple offers a validate button that shows that everything is OK and once the app is in review, it gets rejected for something, that could clearly be detected at compile time (or at least when it is submitted).
If you don't use any external API or framework, CFHashBytes is present only in Swift framework.
I had this issue with two Apps. I have sent this message to the Resolution Center and now both have been approved:
"Hello,
I think that there is an error. The only file that contains that non-public API is libswiftFoundation.dylib, framework used in Swift Apps. Xcode uses it automatically. Please, check it again.
Many thanks."
I hope this helps you.
I'm working on a project in which, I have UIWebView where I need to call some JavaScripts on a webpage in this UIWebView and that particular JavaScript will call my Objective-C native method.
To do that, I'm fetching context from UIWebView and setting my Objective-C object to the context and this object I'm fetching in JavaScriptand In JavaScript, object I'm calling a Objective-c with this function/method.
Here is the code I'm using to do above,
JSContext *context = nil;
context = [_webView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
// enable error logging
[context setExceptionHandler:^(JSContext *context, JSValue *value) {
NSLog(#"WEB JS: %#", value);
}];
context[#"MyObj"] = self;
So my simple question is, whether this way of doing this is ok, in terms of Apple Store. I mean, is there something that can cause my app to get rejected my Apple for App Store?
Thanks.
There is nothing currently in the App Store guidelines that would prohibit what you intend to do.
The ability to initiate functionality from a web server, even if it's via JavaScript in a web view, is common behavior.
Your app is run in a sandbox, so any security concerns are limited to your app. You're not adding code to your app, which is strictly prohibited. You're simply including functionality that may be called at a later time.
The short answer is that it depends on who reviews your app.
I have apps that do something very similar, and they were approved without issue. I have other apps rejected for doing the same thing because the JavaScript was considered "downloaded executable code".
To answer your specific question, I do not believe what you are doing in your Objective-C code will cause a problem with Apple's review, but depending on the source of the JavaScript, that may.
Bottom line is that Apple's review guidelines are still interpreted by humans at Apple, and that interpretation is not perfectly consistent.
I've found out that it's very easy to customize UIPageControl page images (I've checked it for iOS7/8):
[self setValue:[UIImage imageNamed:#"my_icon_for_off_state"] forKey:#"_pageImage"];
[self setValue:[UIImage imageNamed:#"my_icon_for_on_state"] forKey:#"_currentPageImage"];
But I wonder can I publish my app with this code, because these variables are declared as private in UIPageControl?
As per Apple, you can't use private API's in your project.
However we can. Don't worry. Just be honest and while submitting the app, inform them that you have used xyz code.
Apple DON'T approve the app where insecure private API's are used.
Many times, I used private API's and Apple approved it.
Honesty is simplicity.
One of the example
As you've already stated, those properties are declared private by Apple so you will be unable to use them. You can change the tint color of the page "dots" by using pageIndicatorTintColor and currentPageIndicatorTintColor.
I have found an undocumented method for detecting sim card availability in iphone. This method needs CoreTelephony.framework
NSString * CTSIMSupportGetSIMStatus();
int CTGetSignalStrength();
NSString *status = CTSIMSupportGetSIMStatus();
NSLog(#"Sim card status %#",status);
This method works well. can i use this method in my project? If i use this undocumented method, will apple reject my app? plz let me know... Thanks
You can not use undocumented method as Apple says that they can change the implementation for bug fixing or by updating the SDK cause App crash. They do not allow the use of Private API and trace at submission at store. Mostly private method can be found in debugging at Xcode and start with _Underscore so you can try alternative to achieving things if you do not want to get reject your application later at submission.
I'm looking at integrating support for tracking Facebook's new mobile app ads.
I've read the tutorial here:
https://developers.facebook.com/docs/tutorials/mobile-app-ads/
It says:
Include the following code to be executed when your app opens for the first time by user
[FBSettings publishInstall:appId];
So the first question is - where do I put this so that it only invokes the call if the install was driven from Facebook? I don't want FB to get credit for someone who found my app themselves on the app store.
Do I need to manually track whether or not I've called the publishInstall before for this specific user? (The preamble sentence implies this - but the SDK documentation for publishInstall implies otherwise).
And even more confusing is that the SDK FBSettings reference includes shouldAutoPublishInstall which defaults to YES. This would suggest that I don't need to do anything other than have the SDK integrated. So why does the tutorial not mention this as an option?
I assume that the appId is the associated Facebook appId (as opposed to the App Store App ID). This is also not clear from the documentation.
I browsed the sources of facebook iOS SDK, and it seems that guide is wrong.
You are right, that autoPublishInstall is set to YES by default, which means we don't need to invoke [FBSettings publishInstall:appId]; manually. AppId is indeed the facebook app id.
When you invoke openActiveSessionWith.... method, it initializes FBSession with
initWithAppID:permissions:defaultAudience:urlSchemeSuffix:tokenCacheStrategy: which contains in the end [FBSettings autoPublishInstall:self.appID];
+ (void)autoPublishInstall:(NSString *)appID {
if ([FBSettings shouldAutoPublishInstall]) {
dispatch_once(&g_publishInstallOnceToken, ^{
// dispatch_once is great, but not re-entrant. Inside publishInstall we use FBRequest, which will
// cause this function to get invoked a second time. By scheduling the work, we can sidestep the problem.
[[FBSettings class] performSelector:#selector(publishInstall:) withObject:appID afterDelay:FBPublishDelay];
});
}
}
So technically it should report the install out of the box (if I'm not missing something). I'm going to play with it a little more today to see if it works as expected and update answer with results.
Just put it at -[application:didFinishLaunchingWithOptions].
Not all of the apps want to integrate the Facebook login. They only want the feature "mobile app install ads". For these kind of app, they should invoke +[FBSettings publishInstall:appId] manually. On the other hand, if your app has already integrated facebook login, you can assume that the FB sdk has published the installation.
If we just have to put
[FBSettings publishInstall:appId];
manually in
-[application:didFinishLaunchingWithOptions]
how will I identify which install happened from facebook? I don't want FB to get credit for someone who found my app themselves on the app store.
put the code in Appdelegate DidbecomeActive method
- (void)applicationDidBecomeActive:(UIApplication *)application
hope this help :)