I haven't been doing this long, but this is the first time that I've had an app rejected. This is what was in my rejection.
PLA 3.3.1
Your app uses public APIs in an unapproved manner, which does not comply with section 3.3.1 of the Apple Developer Program License Agreement.
Specifically, your app contains a mechanism to keep a device awake. Please see attached screenshot(s) for reference.
Since there is no accurate way of predicting how an API may be modified and what effects those modifications may have, Apple does not permit unapproved uses of public APIs in App Store apps.
The screenshot that they included showed my setup screen where I give users the option to have the application keep the device awake. I tested it, and it only keeps the device awake when in the application. I did not come up with this idea all by myself. I've seen it as an option in other apps.
I am not using anything non-apple to do this. This is my code for keeping the device awake.
UIApplication.sharedApplication().idleTimerDisabled = keepDeviceAwake
where keepDeviceAwake is a Bool that is turned on or off by a user setting.
Is there something wrong with the way that I'm using this or what I'm doing with it?
To give more of an idea, this app is a counter app. I was thinking that it would be really annoying to have to keep turning on the iDevice when counting things, so I give the option to keep the device on while in the app.
The documentation note on idleTimerDisabled says:
You should set this property only if necessary and should be sure to reset it to NO when the need no longer exists. Most apps should let the system turn off the screen when the idle timer elapses. This includes audio apps. With appropriate use of Audio Session Services, playback and recording proceed uninterrupted when the screen turns off. The only apps that should disable the idle timer are mapping apps, games, or programs where the app needs to continue displaying content when user interaction is minimal
Apple probably feels that your app doesn't fall within the guidelines.
Related
IOS 12 introduced some basic screen time settings.
Is there any way to view or change these settings programatically from inside an app or from an external MDM?
Specifically, I would like to be able to change the time limits, the downtime schedule, and/or the list of allowed apps. Ideally from the parent device but from the child device or from an MDM would be acceptable too.
I want a solution like an existing application did.(https://itunes.apple.com/us/app/id981066103 Parental Control - Screen Time)
I'm really interested in this as well, and can share my findings with you here:
There is no possible way to use the screen time / API at the time of writing. Since apps use .entitlements now, private APIs are out of the question as well.
Apple is most likely thinking about releasing a screen time API, since the feature is added in the iOS Simulator.
Apple is rejecting and removing screen time apps for no apparent reason right now.
There is one solution for now though: use MDM. The mobile device management system does not allow you to change the screen time settings on the device, but you do have control over what apps are allowed to be opened. Bind this to some date/time logic and you have a simplified version of the screen time app. The same function can also be used to track the time an app has been opened.
The app you mentioned uses the above MDM solution as well. (Actually, all apps do)
i have a big problem. I am working on an app about accessibility. The app should work through the iPhone microphone to take over sounds from the environment (indoor) and compare them in real time with sounds in the app database (recorded from users previously). If sounds match, the user will be warned by the app through a notification. So... firstly, the app should listen sounds working in background, but after some minutes, iOS closes the app in background automatically. IS THERE SOME SOLUTIONS FOR THIS PROBLEM? TO ALLOW THE APP BE OPENED AND WORKING?
Secondly, do you know in which way is possible compare sounds recorded with sounds listened by microphone in real time?
Really really thank you. 🙏🏻
Regarding the problem that your app is automatically closed, it seems that something was not configured properly in your project.
When the UIBackgroundModes key contains the audio value, the system’s
media frameworks automatically prevent the corresponding app from
being suspended when it moves to the background.
Make sure that you have enabled the "Audio, AirPlay and Picture in Picture" background mode in your project.
Fore the first question:
Because your app will be recording the audio while in background, you can:
set UIBackgroundModes key in your app’s Info.plist file to audio.
It should keep your app alive when you press Home button. See the Declaring Your App’s Supported Background Tasks section
At some point, iOS can kill your app due to some conditions, but
eventually it would restart your app later.
And be careful with this, you might have to deal with Apple Review team to prove that your app is not doing something harm to user privacy. Otherwise, they wouldn't let it go live.
For the second question:
I think you can use some AI/Machine Learning service out there to do so. It's much more accurate and faster than building it your own.
I'm trying to log users individual app usage on iOS9.
I'd rather prefer that it wouldn't use jailbreak limited solutions, self explanatory. Doing the variation of this app on a jailbroken phone shouldn't be hard.
This will certainly not be released on the App Store as Apple wouldn't allow it.
I'm looking for any private API that can do this, any hidden iOS API's that can be used to do this. ANYTHING.
What I've already looked through:
how to determine which apps are background and which app is foreground on iOS by application id
How to know about app launched and details jailbreak iOS 7
Is there a private API to be able to detect what is current foreground app on iOS?
How to monitoring App running in the foreground in iOS8?use the PrivateFrameworks SpringBoardServices
which proved to be relatively helpful - we now can assume that there is some sort of additional access requirement, probably an entitlement, but we don't really know how it should look like
Can you find individual app usage duration using SpringBoard services framework or other private framework?
Find out active application or if on Springboard
Programmatically detect which iOS application is visible to user
However all of these proved to be unhelpful because Apple fixed this security flaw with iOS8 and the method to copy/access the currently front most app bundle identifier no longer works.
Question is: Is there someone who knows a workaround using different tools/exploits that do not require jailbreak?
Ideas:
inspecting the processes running on the device and devising an algorithm that would be able to recognize spikes that mean an app has been launched, which potentially could work, but it probably would be a major pain in the ass. Questions mentioning this solution:
Detect which app is currently running on iOS using sysctl,
Return a list of running background apps/processes in iOS
How to get Names of Background Running Apps
Find Background running apps in iphone
inspecting the phones traffic somehow?
not sure if there is some kernel stuff that I could do
Here is my Reddit version of this question if anyone wants to check it out. Also if it's of any value, here are the runtime headers for iOS9 and list of Apple's private API's.
Unfortunately, I was looking for a similar solution and have come to the conclusion that, at least at this point in time, there are no known methods that will allow you to determine app usage on iOS. Even the MDM providers such as Good, Airwatch, MobileIron, etc. don't seem to be able to do this. If anyone is able to come up with a solution, I'd love to see it.
For now, however, I think we would have seen a solution if someone had one that worked on the latest iOS.
sysctl is still open but they block certain combinations of selectors. I did this on iOS 7 and gave Apple Product Security the code. They won't patch iOS 7 but rely on App Review. iPhone 4 is wide open.
Is there any possibility to know which apps are in the background (Those apps that appear when you double tap home button)?
For 3rd party apps, no. Not in a reliable, App Store safe, future proof way. Think of your app as siloed, unaware of what else is running, and you'll be pretty much in the mindset Apple want (and try to technically enforce).
For other apps developed by you, you can use shared containers to write load/unload data each time one of your apps opens/closes, and work out what's currently running.
This is not possible on iOS with public api. There might be private api calls that do this, even though I don't think you will have access to them while running in the sandbox. This however might be possible on jailbroken devices, but you will not be able to submit to the app store with such api usage, unless you know how to hide that from apple.
Also please note that apps shown in the app switcher are not necessarily running. The app switcher shows every app that has been running in the past which the user didn't force-quit. If the user does not force quit an app, every app that has ever been launched is shown in the app switcher. If iOS decides to terminate an app because of memory needs, the app is still shown in the app switcher. This is one of the reasons why everyone should implement state restoration, as the user does not know whether an app is currently running or not!
This is a strange one, I have a need to create an iOS app that runs in the background on an iOS device, but can not be visible on the Home screen of the device. The app may need to show up in Settings to configure a few options, but it mostly needs to run behind the scenes.
I do not need to publish this app on the app store, it is strictly an enterprise app for my company.
Does anyone know how this kind of behavior might be achieved? Configuration profiles? API's? etc?
Edit: Jailbreaking the device is not really an option for us. We have to keep the devices as they are.
Backgrounding
There are several methods to get permanent background execution:
a) Silent audio which is mentioned by JRG-Developer
b) Usage of beginBackgroundTaskWithExpirationHandler + turning location manager on/off (it will reset remaining time to 600 seconds)
Making app invisible
You can use SBAppTags in Info.plist (take a look at this: How to remove app icon programatically from jail broken iPhone app?)
It will make your icon not visible on Home screen.
I've no idea how you can tackle the not be visible on the home screen criteria, but there are certain services that are allowed to be run in the background continuously, notably:
Background Audio (even silent audio)
While this is indeed very hacky, short of jailbreaking the devices, this may be your best bet.
While it's unlikely / very difficult to get past the review process, in the event for some reason you do need to (attempt) to publish this app to the App Store, some apps are even available on the App Store which take advantage of this hack, such as PasteBot.
You should definitely read their write-up here about getting their app's Cut-and-Paste functionality to work while in the background:
http://tapbots.com/blog/pastebot/pastebot-music-in-background
Another out-of-the-box idea, why not use Android devices instead, which do support multitasking?
Two methods:
Jailbreak. A jailbroken iPhone is essentially a Mac and you can use all Mac UNIX programming tricks - spawn a daemon (you can even ask launchd to do that), or something. You can set up enteprise-wise Cydia source. Refer to saurik's website for a walkthrough and set up an experimental server using Ubuntu (which used apt too)
A non-jailbreak way may be possible, but it will depend on what your app is doing. You can try use enterprise-wise push notifications.
Given that this is impossible to do on non jailbroken phones, I'd suggest the following:
develop a directory app, or a phone list app, something that is specific to your company.
have it connect to a web service once a day to register the device ID (so you know the user has not deleted the app)
tell users they need to keep the app open at all times (and if a user's device does not register one day, send them an email asking them to launch the app).
Now you can send back whatever you want with the app. If they kill it, you'll know the next day when you have a script look at the logs.
If you think this is a terrible idea, it is, but its the best you are going to get on iOS right now.
EDIT: you could send a notification every day - say in the AM - to make sure the user opened the app if it wasn't running.
From my experince, this kind of behaviour cannot be achieved on iOS. When an app enters into background, it is active only for a small particular amount of time. After that, it goes into hybernate state. It stops working. So the behaviour you said can not be achieved without abusing iOS workflow. Thats why some call iOS's multitasking as not true multitasking. Only jailbreaking might help your case. That was for one case. The second one where the app cannot be seen on home screen is again, impossible. It has to be on springboard to run.