I'm writing a small Mac application (in Obj-C) which runs the following command:
system("killall Finder");
I wanted to see what would happen if I sandbox the app (as sandboxing will be required on June 01), and the app wouldn't work. I got the following response:
killall: warning: kill -TERM 6524: Operation not permitted
Is there any way to get around that? As in a specific entitlement to add or another way to run the command?
Thanks in advance.
Your app completely goes against the spirit of the sandbox, so there's almost no chance that the MAS reviewers will accept it. Also, you may be surprised at what "defaults write com.apple.finder" does from inside your sandbox—basically, nothing useful. You'll have to use a temporary exception entitlement to home-relative /Library/Preferences/com.apple.finder.plist, use some non-sandbox-affected API to get the path to home (e.g., getpwent()->pw_dir), and load and save the plist directly. And then you'll discover that there is no way to call on a non-child process from a sandboxed app, period, no way around it—and if you try to system killall, it ends up running inside the same sandbox as you, and therefore has the same limitations.
However, you asked a specific question as to whether there's a way around that system killall failing, and there are at least three (not counting holes in the sandbox which have either been plugged by 10.7.4 or will surely be plugged soon):
You can create a helper app that isn't sandboxed, that does the killall for you. The only two App Store-approved ways to do this are XPC and SMLoginItemSetEnabled. And you're not allowed to enable the helper without the user explicitly telling you to do so.
You can send Finder an Apple Event asking it to quit, instead of signaling it. The easiest way to do this is to execute the Applescript 'tell app "Finder" to quit'. At least for 10.7.3 and earlier, you'll need a temporary exception entitlement to send Apple Events to com.apple.finder. (There may be different mechanisms for future OS versions, but nobody can discuss them outside the NDA forums.)
You can send an Apple Event to some other process—like System Events—to kill Finder on your behalf.
And so on.
If you have a good reason you can still kill applications like this:
How can I terminate my app in a helper app with sanboxing enabled?
Related
I have an application where I need to create local notifications via polling without doing push - primarily due to client infrastructure limitations and their security model.
I've read: http://www.objc.io/issue-5/multitasking.html, I've seen David Chan's WWDC presentation - where single push messages kick off download tasks - but what I truly need is background fetch - on a regular basis - like every ten minutes - in iOS 7.
I've seen the VOIP hacks. No. What non-hack way is there to do this without user interaction or push messages? Any examples you can point me to?
Here's what I know:
Background data tasks will work in the debugger but if you can get a console on an IPA, you'll quickly find out they really are prohibited (thereby invalidated many examples).
Background URL tasks require custom delegates - but fetch completion handlers are iffy. This too I found with an IPA and console.
I would love to avoid using the AFNetworking lib - for something quite simple.
Background fetch is not a reliable solution - you are at the mercy of the OS, and it is not very merciful. Abusing iOS background modes is not a reliable solution - Apple is known to reject applications that enable background modes, such as location, VOIP and music playback, without a legitimate reason. Background URL tasks are not something you can rely upon to wake your app; they will wake it, but the app will not be awake enough in the background to enqueue a background URL task.
Your best and most intended method is still background fetch, but be prepared to be disappointed. Your app will not be woken app in the interval you need. Also, the user can kill the app in the app switcher screen, causing your app to never wake up until opened.
No real reliable method other than push. You need to insist with your client for the sake of user experience.
Unfortunately there is no "reliable" way to do that on iOS. With the background fetch API you are not guaranteed to have process run when you would like it run. As you've said, you've already looked at the API so i'm probably telling you something that you already know. A local notification wouldn't solve your issue either as this isn't a way that you can wake your application up and kick off network events. This is behavior that Apple doesn't want as this would negate the whole purpose of their background task coalescing.
You really need to have a push mechanism in place for something like this, so if this is something that is needed, then you may have to stress that to the client.
When we deactivate a WP app, it can be tombstoned and terminated later by the OS. I need to save some unsaved app data to a persistent storage when the process is terminated, but not before this. Obviously, the Deactivated event cannot be used for this purpose as it is raised immediately when an app is moved to the background; the Close event is also not the event we need as it si not raised when the app process is terminated by the OS. Is there a special Windows Phone app event for that, something like Application_Terminated?
The problem is that the operating system only tombstones your app when it is under severe resource pressure. At the time it is not practical to wake up the app and run app code because it might risk whatever is currently in the foreground. This limitation exists on all modern mobile operating systems (Android, IOS included). This is just the cost of operating in a battery/resource friendly environment.
Having said that, it sounds like your backing store does not disambiguate between data the user "saved" and data that is just being cached until the user can finish the transaction. It would be useful to build the idea in. Think of it the way some of the smarter web sites on the internet now work. You can navigate away while you were in the middle of entering data and when you come back the site presents you with the partially filled form. The site understands that you weren't "done" but it respects the fact that you had provided some of the information you'd need to get "done".
What I'm saying here is that the problem is easily fixed by understanding and accommodating the way your users are likely to use the app. Thinking of your app like a web site (at least in this context) helps out things into perspective. Sorry about the longish answer. I hope it helps :)
There is no such event. You should save your state on Deactivated so that if the application is removed from memory (tombstoned) you can set yourself up again upon reactivation. If your problem is figuring out whether or not you need to restore state on Activated, check out the ActivatedEventArgs.IsApplicationInstancePreserved flag (http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.shell.activatedeventargs.isapplicationinstancepreserved(v=vs.105).aspx). This flag tells you whether your app was tombstoned. If it wasn't, you can throw away the old state or overwrite it the next time you are deactivated.
Coming from Android/WP7 and having been involved in Symbian projects by the past, i would like now to exactly understand the Symbian App life cycle. I want to understand how the Apps are killed.. if they are..
I found this:
"The Symbian platform is a modern preemptive multitasking operating system. Applications are created in their own process, running in a single main thread. The kernel preemptively schedules all threads in the system, based on their priority. While it is possible to create secondary threads, Symbian strongly encourages applications to co-operatively multi-task using active objects. ". Ref-link
"(..) applications may be up and running at the same time and the user may switch between active applications. When a asynchronous event occurred, running application is moved to the background but it remains active". Ref-link
It seems to me that the Apps are never killed, even when they are in background..
My question is: If the system does not kill them, how the system deals with the RAM issue? What about the possible battery drain? Does it mean that Symbian allows starting each single App, till there is not enough memory? Is there a specific meaning about the use of the Cancel/Back key that might destroy the App in certain conditions?
In UIQ framework i remember a lowMemory() call-back, but one never used that..
Thanks, for your help..
Symbian Apps are indeed never killed. That allows you to have several apps running in parallel without problems. Every app should of course provide the Exit command that closes the app. Back/Hide command just leaves the app runnning and takes user back to the menu. Also every well-written app should also manage his background tasks and allow to stop them when needed.
FYI, in Symbian there might be several background tasks running that are automatically started when phone is powered on. You can get the list of them when asking for a list of processes. You can also kill any process or app if your app has enough capabilities.
I have a windows mobile application
I have noticed that it properly terminate on exiting, they simply minimize and take up memory. I need to cehck whether any instance of the same application is running in the taskmanager.If exists, i need to kill the process.
I need to write small app that would loop through all open application processes and terminate the required one.
Does such an application exist? If not, which onecould I use to write my own app for it?
Typically this is not how you solve this problem.
You should hold a 'mutex' in your application, and when it launches a second time, you first check this mutex, and if it's taken, you know your app is already running.
Find an appropriate global mutex to hold, and then check for it (I'm not sure what sort you can use on whatever version of Windows Mobile you are targetting, but a trivial search should help you find the answer).
If your app shows an [X] in the corner that's a Minimize button. Change the MinimizeButton property of the form and it will become an [ok] button which will close it.
The CF under Windows Mobile already enforces application singleton behavior. If the app is already running, the CF will look for it, find it, and bring it to the fore for you. No extra work needed.
If you really want to find the process and terminate it, that's done with the toolhelp API set. You can P/Invoke it or use the classes in the Smart Device Framework.
How can I terminate another app that is running in cooca. Let's say I have iTunes running, and I type in quit in my app, it would quit itunes. "iTunes" is just an example, it could be anything the user wants. I can open any app from my application, but I want to know how to close any app running.
thanks
kevin
AppleScript is a pretty high-level way to send a single Quit event. SIGTERM is a pretty brute-force, low-level way.
The correct way to quit another application is to obtain its Process Serial Number (psn) and send it a kAEQuitApplication Apple event with these two lines of code:
result = AEBuildAppleEvent( kCoreEventClass, kAEQuitApplication, typeProcessSerialNumber, ¤tProcessPSN,
sizeof(ProcessSerialNumber), kAutoGenerateReturnID, kAnyTransactionID, &tAppleEvent, &tAEBuildError,"");
result = AESend( &tAppleEvent, &tReply, kAEAlwaysInteract+kAENoReply, kAENormalPriority, kNoTimeOut, nil, nil );
You can do this from C, C++, or Objective-C, and you have to link with CoreServices.framework.
If you're running on Mac OS X 10.6, Snow Leopard, you can use the new NSRunningApplication terminate method.
For high-level applications like iTunes, based on Carbon or Cocoa, they're going to respond to Applescript. "Quit" is part of the standard package. You just need to send:
tell application "iTunes" to quit
There are lots of ways to do that. The simplest to implement is to make a system call to osascript:
osascript -e 'tell application "iTunes" to quit'
You can go up from there to more powerful tools like Apple Events, which would be very appropriate for this problem. You could even go so far as Scripting Bridge, but for terminating an app, that would be overkill.
This will only work for programs that respond to Applescript, but that should be any program that you would see in your dock (and which I assume you mean by "applications"). For lower-level processes like daemons, you need other techniques like launchctl or kill, but we can talk about those if you need them.