Interpreting nm output after rejected app - ios

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.

Related

Is there a way to recognize, that the app was installed thru firebase dynamic link in didFinishLaunchingWithOptions?

I am implementing firebase dynamic links in my iOS app and I can already parse the link, redirect to AppStore etc. Now I want to distinguish the first run of the app, when user installs it from the dynamic link - I want to skip the intro and show him the content that is expected to be shown.
Is there some parameter, that I could catch in application(_:didFinishLaunchingWithOptions:) so I could say that it was launched thru the dynamic link?
The method application(_:continueUserActivity:userActivity:restorationHandler:) is called later, so the intro is already launched.
This case is difficult to test, because you have to have your app published on the AppStore.
You actually don't need to have the app published in the App Store for this to work — clicking a link, closing the App Store, and then installing an app build through Xcode (or any other beta distribution platform like TestFlight or Fabric) has exactly the same effect.
According to the Firebase docs, the method that is called for the first install is openURL (no, this makes no sense to me either). The continueUserActivity method is for Universal Links, and is only used if the app is already installed when a link is opened.
I am not aware of any way to detect when the app is opening for the first time after install from a 'deferred' link, but you could simply route directly to the shared content (skipping the intro) whenever a deep link is present. If a deep link is NOT present, show the regular intro.
Alternative Option
You could check out Branch.io (full disclosure: I'm on the Branch team). Amongst other things, Branch is a great, free drop-in replacement for Firebase Dynamic Links with a ton of additional functionality. Here is an example of all the parameters Branch returns immediately in didFinishLaunchingWithOptions:
{
"branch_view_enabled" = 0;
"browser_fingerprint_id" = "<null>";
data = "{
\"+is_first_session\":false,
\"+clicked_branch_link\":true,
\"+match_guaranteed\":true,
\"$canonical_identifier\":\"room/OrangeOak\",
\"$exp_date\":0,
\"$identity_id\":\"308073965526600507\",
\"$og_title\":\"Orange Oak\",
\"$one_time_use\":false,
\"$publicly_indexable\":1,
\"room_name\":\"Orange Oak\", // this is a custom param, of which you may have an unlimited number
\"~channel\":\"pasteboard\",
\"~creation_source\":3,
\"~feature\":\"sharing\",
\"~id\":\"319180030632948530\",
\"+click_timestamp\":1477336707,
\"~referring_link\":\"https://branchmaps.app.link/qTLPNAJ0Jx\"
}";
"device_fingerprint_id" = 308073965409112574;
"identity_id" = 308073965526600507;
link = "https://branchmaps.app.link/?%24identity_id=308073965526600507";
"session_id" = 319180164046538734;
}
You can read more about these parameters on the Branch documentation here.
Hmm... as far as I'm aware, there's not really anything you can catch in the application:(_:didFinishLaunchingWithOptions) phase that would let you know the app was being opened by a dynamic link. You're going to have to wait until the continueUserActivity call, as you mentioned.
That said, FIRDynamicLinks.dynamicLinks()?.handleUniversalLink returns a boolean value nearly instantly, so you should be able to take advantage of that to short-circuit your into animation without it being a bad user experience. The callback itself might not happen until several milliseconds later, depending on if it's a shortened dynamic link (which requires a network call) or an expanded one (which doesn't).

Flurry Crash Reporting not working

I have tried like below in my app delegate. Can you please tell me what's going wrong here:
Flurry.setDebugLogEnabled(true)
Flurry.setLogLevel(FlurryLogLevelDebug)
Flurry.setEventLoggingEnabled(true)
Flurry.setBackgroundSessionEnabled(true)
Flurry.setCrashReportingEnabled(true)
Flurry.setShowErrorInLogEnabled(true)
Flurry.startSession("KEY")
As stated in this post please check with the support from Flurry first, to make sure that this isn't normal behaviour. The post also states that it can take up to 8 hours for a crash to appear in the dashboard.
Flurry support page : https://developer.yahoo.com/flurry/support.html
Make sure to include your API-key in the email, so they can actually check on your problem.

redirect_uri_mismatch Unity Google API on iOS

I created an app in Unity with Google Play Leaderboard support. I could easily make it work on Android, then I moved to OSX to build it for iPhone too.
First I got a problem, that Apple won't accept any bundle identifier with the '_' character in it, but my Android app bundle identifier had 2 of them...
However I found out, that in the Google Developer Console I can link another app to my app (to use the same Leaderboard) for iOS too, so I was quite happy. Unfortunately this doesn't seem to work. I get the *redirect_uri_mismatch* error message every time I try to log in.
On Android I used the UnityGPGPlugin but as it didn't work for me on iOS, I tried the PlayGameServices too. In UnityGPGPlugin I could set only the Application ID, so I thought that's why it is not working. In the PlayGameServices plugin there are two fields, one for the Application ID and one for the Client ID that made it look like that's really what I need. Unfortunately the error is still present and I really don't know what I could do with it. Here is the well known message:
Error: redirect_uri_mismatch
Request Details
cookie_policy_enforce=false
scope=https://www.googleapis.com/auth/appstate
https://www.googleapis.com/auth/games
https://www.googleapis.com/auth/plus.login
https://www.googleapis.com/auth/plus.moments.write
https://www.googleapis.com/auth/plus.me
https://www.googleapis.com/auth/plus.profile.agerange.read
https://www.googleapis.com/auth/plus.profile.language.read
https://www.googleapis.com/auth/plus.circles.members.read
response_type=code
access_type=offline
redirect_uri= < my bundle identifier without '_' characters >:/oauth2callback
state=16885367
gpsdk=1.5.0
verifier=12647966
display=page
client_id=123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
hl=en
The debug log contains only this:
2014-03-16 14:21:19.507 <my app>[1699:60b] GPGSAuthenticateWithCallback.
2014-03-16 14:21:19.509 <my app>[1699:60b] GPGSManager initializing and authenticating.
2014-03-16 14:21:19.512 <my app>[1699:60b] GPPSignIn initialized.
2014-03-16 14:21:19.514 <my app>[1699:60b] GPPSignIn attempting sign in now.
-> applicationWillResignActive()
-> applicationDidEnterBackground()
Does anyone know how could I solve this problem?
Thanks in advance!
Edit:
Maybe it wasn't obvious, but I have 2 bundle identifiers, both of them are linked to the same game service in Google Play Developer Console. The com.x.a_b_c belongs to the Android app, the com.x.abc belongs to the iOS app.
I was having redirect_uri_mismatch error while using UnityGPGPlugin. I was using "123456789123" as my Application ID instead of "123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".
However, I manage to get through the Google Sign In page after changing all my setup to "123456789123-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" as my Application ID. Including the GPGApplicationID in Info.plist.
Sad to say that I am having another problem now, but at least that's how I manage to get through that error. :)

iOS Facebook SDK error language

I am wondering if the Facebook SDK for iOS provides a method for localizing the error messages.
From here: https://developers.facebook.com/docs/ios/errors/ I learned that there's an easy way to get a description of e.g. Login errors which you can display to the user:
[FBErrorUtility userMessageForError:error];
But that only returns an english version. Is there any way to automatically translate that to a different language? Or a different method to return a localized string? Otherwise this convenient method would be kind of useless for non-english apps.
Regards
Kim
Ok, I figured it out myself.
I had to create a bundle file, set it in the .plist under the key "FacebookBundleName" and overwrite the needed Error Message key/value pairs there.
Took me a while to get it running, but the Scrumptious sample helped me figure it out.
See "How can I localize the Facebook images and strings?" in
https://developers.facebook.com/docs/ios/troubleshooting/

xcode apigee logInUserWithFacebook extra parameter?

I'm using Apigee for my iphone/ipad app.
Like many apps today, mine requires a login via Facebook and Apigee has a function specifically for this in the iOs framework, here's how it's called:
[ApigeeDataClient logInUserWithFacebook:[FBSession activeSession].accessTokenData.accessToken];
As far as my code goes, everything works well up until the above line. I'm receiving the following error.
Response: {"error":"invalid_request","error_description":"missing access token"}
However check out how the function is making the call (from the logs):
Synch outgoing call: 'https://api.usergrid.com/sgfishing/deepseafishing/auth/facebook?ql=fb_access_token=CAADrhKxrQp4BANfZCMuZBdOwUL9nc0H4VzZC1EXVLjABRbcrucTlUgwlKczFinl51GIWyBM5nlZBX1RF84azFAEOfChqN7vgSmvqgwybV8iPU2xjncZB9T5YTdY0pesJkHsSlvOafMhQ6MfIa6qdZCbTYBZCFB2oIPgEnro4runJKcqCy68wZCFQwyIzACVThAC3IEjZADs36hToQxhYZBzAWVhbKlcqJQsroZD'
I would like to bring your attention to this ...facebook?<b>ql=</b>fb_access_token=CAADrh....
I'm not sure why ql= is there, I've checked the definition of logInUserWithFacebook and ql= is nowhere to be found.
Any help would be greatly appreciated.
This is a bug in our iOS SDK. It has been fixed in version 2.0.9 of our SDK (released yesterday).
?ql= is typically used for query language statements see if there is any such code around in your program
This just a tip...may help

Resources