how to disable hooks in a mobile substrate tweak - ios

Using logos, I can initiate a group of hooks using %init(groupName) I was wondering if there is a way to disable the group of hooks as well. I need my tweak to be disabled while the phone is locked.
Currently, I'm calling init in my tweak whenever the lockscreen is dismissed, and killing the process (mobilemail) whenever the lockscreen is activated. That seems like a crude solution though, is there something better?
thanks for the help

1) No, you cannot disable hooks in the sense you're thinking of once they're initialized.
2) Yes, killing the process will disable the tweak (because it's injected into the process when the process is spawned, and runs within that process). However, you definitely should not do that. Instead, you should enable the tweak when the user unlocks the device and disable it when they lock it. You could even simply use a static boolean to do this if you want to be über simple. You cannot "unload" the code, per se, but you can have it stop executing if a condition is not met for sure.
Happy coding.

Related

Is it mandatory to call NSUserDefaults synchronize method?

Please, anyone, help me: Is calling NSUserDefaults's synchronize() method mandatory?. If I don't call it, what will happen? My application is working fine without it.
No.
Since iOS12, it isn't mandatory anymore.
Apple says:
This method is unnecessary and shouldn't be used.
You can find more information on iOS12 release note:
UserDefaults
NSUserDefaults has several bug fixes and improvements:
Removed synchronization requirements. It's no longer necessary to use synchronize, CFPreferencesAppSynchronize, or CFPreferencesSynchronize. These methods will be deprecated in a future version of the OS.
Now that you don't need to call these synchronization methods, the performance characteristics of NSUserDefaults and Preferences Utilities are slightly different: The time taken for enqueueing write operations is now paid by the writing thread, rather than by the next thread to call synchronize or do a read operation.
From the docs:
Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.
Meaning that if you kill the app right after something is written to the defaults without the periodic interval catching it, it will get lost. You probably did not kill the app right after a write event yet which is why your app seems to work fine so far.
Normally it works perfectly fine and you only have to use it in special cases, for example when the app will close directly after writing to NSUserDefaults. So you can simply add the synchronize method to the corresponding AppDelegate-method.
As others have said, you don't normally have to call synchronize at all.
Normally the system calls it for you so your defaults changes get written.
However, when working with Xcode it's pretty common to terminate your app by pressing command period or clicking the stop button. In that case it terminates the app without warning and your user defaults changes will quite likely not be written out, and will be lost.
This can be a good thing or a bad thing, depending on what you want. It's certainly confusing.
You can "fix" it by calling synchronize each time you make a change, or on some time interval. However that does slow your app down and increase it's power requirements (both by very small amounts.) If you are in a loop, writing changes to 10,000 server or Core Data records, and you change user defaults after each pass, then calling synchronize after each one might have a measurable effect on app speed and on battery life. In most cases you're not likely to notice the difference however.

Is it possible for your APP network status indicator to be turned on by something other than your own App?

I have couple method that depend on the network status indicator being hidden or not based on my App. I was wondering if it is possible something outside of your App control is able to turn it off or on. Any clarification will be appreciated. I downloaded an App in background and received an email in the background the indicator didn't show.
If you're referring to the networkActivityIndicatorVisible property of UIApplication, I don't believe any outside application will manipulate that property, since it is specific to the running application.
I assume you're asking because of this question, and I would recommend, like others have, not to use this to determine whether a network call has completed or not. I would put the code you want to execute at completion in a callback or delegate, depending on how the call is made. Attaching it to the networkActivityIndicatorVisible property can lead to problems if you have code in the future that shows and hides this, but you don't want this method to execute anymore.

Restarting Main Thread in IOS

I have an application/game which I am adding a restart button to. The easiest thing for me to do this is if there was a bit of code which would release all objects created by the app running and restart the main thread (there are many of them including timers which may be running when the reset button is being pressed).
Is there any such code?
I understand that it may be possible to run the app in a secondary thread and refresh that but I dont have any threading experience.
can anyone help?
The only thing i know is you can force kill your app but be prepared as it will be rejected by apple and even if you get success in killing app then you cannot restart it.
It is not possible to restart the main thread or anything similar. You're probably thinking of the wrong design. Think of it from an object oriented perspective: what you need to do is to restore the state of some objects that keep track of the state of your application.
So say you have a Game class that has some properties like:
level
points
what you'd have to do is restore those to 0 (or whatever the initial value is).
Hope you get the idea ;)
there is not easy way to do that, if you want to restart the game or level you will have to recreate the level, by re assign the level variables redrawing the correct components etc..., you will not be able to restart the game or level by restarting a thread,

Waiting for applications to finish loading [duplicate]

I have an application which needs to run several other applications in chain. I am running them via ShellExecuteEx. The order of running each of the apps is very important cause they are dependant on each other. For example:
Start(App1);
If App1.IsRunning then
Start(App2);
If App2.IsRunning then
Start(App3);
.........................
If App(N-1).IsRunning then
Start(App(N));
Everything works fine but there is a one possible problem:
ShellExecuteEx starts the application, and return almost immediately. The problem might arise when for example App1 has started properly but has not finished some internal tasks, it is not yet ready to use. But ShellExecuteEx is already starting App2 which depends on the App1, and App2 won't start properly because it needs fully initialized App1.
Please note, that I don't want to wait for App(N-1) to finish and then start AppN.
I don't know if this is possible to solve with ShellExecuteEx, I've tried to use
SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;
but without any effect.
After starting the AppN application I have a handle to the process. If I assume that the application is initialized after its main window is created (all of Apps have a window), can I somehow put a hook on its message queue and wait until WM_CREATE appears or maybe WM_ACTIVATE? In pressence of such message my Application would know that it can move on.
It's just an idea. However, I don't know how to put such hook. So if you could help me in this or you have a better idea that would be great:)
Also, the solution must work on Windows XP and above.
Thanks for your time.
Edited
#Cosmic Prund: I don't understand why did you delete your answer? I might try your idea...
You can probably achieve what you need by calling WaitForInputIdle() on each process handle returned by ShellExecute().
Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.
If your application has some custom initialization logic that doesn't run in UI thread then WaitForInputIdle might not help. In that case you need a mechanism to signal the previous app that you're done initializing.
For signaling you can use named pipes, sockets, some RPC mechanism or a simple file based lock.
You can always use IPC and Interpocess Synchronization to make your application communicate with (and wait for, if needed) each other, as long as you code both applications.

Automated sleep log

I would like to create a device that will log when a person falls asleep. Of course, someone can't just open a software application and make an entry say "fall asleep, 10:13pm" and be asleep a few seconds later. Instead, I was thinking about hacking a blackberry to log whenever a person powers it on to check the current time. The specific algorithm is not important, but is it possible to write a piece of code be written to intercept the power on button and write the current time/date to a file? If so, how is it done?
Also, if anyone has a simpler idea, please share.
I haven't tested it, but since you're asking for ideas:
You have your application running in background (or even an app which doesn't extend UIapplication) and have a Task (using Timer and TimerTask) that repeatedly checks if Backlight.isEnabled() returns true. If it does - somebody is using the phone. You can even incorporate an AlertListener class to check when the user has been woken up ;)
The downside of this solution (if it works) is that it is something of a 'busy waiting loop', so intercepting some event would be much better.
As far as writing down the current time is concerned - it's possible and sample code snippets are everywhere, you can of course use the persistent store or an SQLite table to aggregate the results in an interesting way.
Funny thing is I've been thinking about an app like this lately - it might be an good idea.

Resources