Yes they did!
Post
Replies
Boosts
Views
Activity
I think that you may have a problem.Disabling ads 'for adults' is a far cry from "..include human review of ad creatives for age appropriateness". These are kids. You want to exclude lots of ads beyond just those 'for adults'. Check the documentation for your ad provider and see if they have a 'kids category'. If they do, they have a URL that provides that description. Include that URL in the notes to App Review.
Got it; I am familiar with "- (void)application:(UIApplication *)application performFetchWithCompletionHandler:"(It is deprecated as of iOS13)You may have a different issue that needs to be addressed. The system monitors the use of background fetches and limits it based on its calculations. In your case it sounds like the system is determining that the fetch rate is too high for the app's needs. Are you fetching very often? Are you returning 'nodata' in a timely fashion? Note: "Calling the completion handler in a timely manner, and with an accurate result [which can include saying that no new data was available], helps determine how much future execution time your app receives. If you take too long to update your app, the system may schedule your app less frequently in the future to save power."Also, have you checked UIBackgroundRefreshStatusto be sure it is still set?
I am not sure about B2B but an regular app has an "Apple Id" on the "App Information" page on "My Apps" on "App Store Connect". With that id (1234567890 below) the url is: https://itunes.apple.com/app/id1234567890Distribution of the B2B app is different - a user doesn't download a B2B app using the App Store.
All apps have to do something 'useful' before a purchase is made. You can have the app open and show all the great things it would do if the user purchased a subscription. You can explain the terms of the subscription to the user and give the user the option of purchasing the subscritpion. That is usually enough to satisfy App Review. But no one can say what App Review will or will not do. Consider the app pre-subscription an opportunity to market the subscription.
The guidelines are here:https://developer.apple.com/app-store/review/guidelines/#kids-categoryThey include section 1.3 which states: Apps in the Kids Category should not include ... third-party advertising. ... Third-party contextual advertising may also be permitted in limited cases provided that the services have publicly documented practices and policies for Kids Category apps that include human review of ad creatives for age appropriateness.Your app seems to violate the first sentence above. But the second sentence allows an exception. App Review is assuming you fit into that exception and is asking for that documentation from your ad provider. I do not know if Admob satisfies that exception. If it exists, App Review is asking for you to send that documentation to them, not to include it in the app. If it does not exists then you must remove the ads to stay in the Kids Category.
So it sounds like you are already one step ahead of me - you already have the system in which data is transfered from one GKMatch to another. So now go from 2 players to 4 players per GKMatch. Once you have done that, increase the number of GKMatches until the system starts to be unstable. At that point there are two paths - 1) eliminate that instability with tweaks to prevent losing a GKMatch or 2) push the structure down a level by having a 'follower' in one 4 player GKMatch become their own 'leader' and create a second layer of multiple GKMatches. I'd definitely vote for #2.
If you collect the receipt after a call to updatedTransactions with a state of purchased (not failed) then that receipt should be the most recent. But at that moment you cannot rely on the 'latest_receipt_info' field returned by the Apple servers - you rely on what is in the receipt itself.
> Sorry if this is obvious, but maybe I need to explicitly say that my app has a local cache/replica DB and can work offline. I thought that was normal when using CloudKit, so I didn’t mention it.You obviously have a vision for how you want this to work. I thought you were unaware of the system built into CloudKit that handles these conflicts so I mentioned it. But you can certainly ignore the system that is integral to CloudKit and make your own. Best of luck to you!
This:https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchmakingwithGameCenter/MatchmakingwithGameCenter.html#//apple_ref/doc/uid/TP40008304-CH12-SW7says that a peer-to-peer GKMatch is limited to 4 players so you are trying to do something that is not supported.Regarding multiple GKMatches - a GKMatch never breaks if you limit it to 4 players. Therefore I suspect a daisy chain will work fine.
1) regarding keychain: The keychain is a protected memory space available for all apps. Seek out something called 'keychainItemWrapper". The advantage of the keychain is that, until Apple executes its newly announced policy change, keychain entries do not get deleted when an app is deleted from the device. All other files get deleted when the app is deleted from the device. I do not know if iCloud key-value file gets deleted, but I think not.2) good to know that you do not require logging out of Apple ID.3)> Turning off background app refresh before reinstalling the appI am not familiar with 'background app refresh' - what is that?4)The root problem is that users can find themselves never being allocated background time for the app to perform web fetches. ThIs this a race issue where the app reinstalls and starts faster than the app can download something in the background? If so, detect that it is a reinstallation and delay starting the app until the background download completes itself.
>the user will be redirected to a webview page to complete his payment, is that match with the app store review guidelines or my app will be rejectedThis will be the least of your problems.The guidleines are here:https://developer.apple.com/app-store/review/guidelines/#gaming-gambling-and-lotteries
>When updatedTransactions method returns SKPaymentTransactionStatePurchased statate, we send the receipt to the server for validation.Please clarify that you decode that receipt and don't rely on the Apple's 'latest_receipt_info' field which may lag in time behind the current receipt. If so, check your code to be sure you actually retrieve the new receipt in updatedTransactions.>server returns validation error because of empty in_app_purchaseCan you please explain why the 'server returns validation error' rather than the server returning the decoded receipt which may or may not contain an in_app_purchase field. What error?>we can get strange alphanumeric transactionId'sThat sounds like a hack attempt by the user
'last write wins' does not refer to modificationDate it refers to the order of the write - and that is exactly what would happen if you chose CKRecordSaveAllKeys here:https://developer.apple.com/documentation/cloudkit/ckrecordsavepolicy?language=objc
> The code I'm writing is the part that tries to resolve/merge the conflict (ideally without user interaction) after the conflict is detectedI was answering the question 'do we need a local modificationDate field' - you don't. Again - time (modifciationDate) doesn't matter, version does. CloudKit already has a serverRecordChanged error that compares version downloaded and version being changed, not times, and warns the device that there is a conflict. That's the answer to the question asked.Now, what to do when you detect a conflict? As you indicate, there are lots of ways of handling it. But none of those ways depends on modificationDate.