I have a game app that, once completed, gives the option to restart. Instead of restarting each method, variable, class, etc separately, I was hoping I could just restart the whole app with the click of a button. Is there a method in swift/xcode to do this?
Thanks!
No, there's not. Best way is to set up an architecture where it's easy to reset everything because all of your state is stored in one place.
For example, inside your AppDelegate/SceneDelegate (whichever architecture you're using), you could have a GameState object that controls all aspects of the game, either by directly holding all of the properties or at least being the common ancestor of everything. Then, when it's time to reset, just create a new instance of GameState().
Related
I'm having a very simple problem with my implemented 3D Touch dynamic quick action shortcuts.
I want the shortcuts to be cleared whenever the app is terminated (by double clicking the Home button and swiping up).
I am calling UIApplication.sharedApplication().shortcutItems.removeAll() as follows:
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
UIApplication .sharedApplication().shortcutItems?.removeAll()
self.saveContext()
}
However it has no effect, and the quick actions still show when 3D touch is used.
If I place UIApplication.sharedApplication().shortcutItems?.removeAll() inside
func applicationDidEnterBackground(application: UIApplication), this works exactly as intended...
I read something about applicationDidEnterBackground being the function used in most cases due to background processing or something...but there has to be a way to achieve what I want when the user terminates the app using the app monitor swipe up.
Thanks
Didn't tried this. But this tweak should work.
Start a background task on applicationWillTerminate and end it after some small delay. In the mean time, you can call 'UIApplication .sharedApplication().shortcutItems?.removeAll()'.
This will hopefully clear the shortcut items.
There are dynamic and static quick actions. The first kind you define through the shortcutItems property of the UIApplication instance (like in your example). The second kind you register in the plist file.
From the documentation:
Your code creates dynamic quick actions, and registers them with your app object, at runtime.
The system registers your static quick actions when your app is installed.
If a user installs an update for your app but has not yet launched the update, pressing your Home screen icon shows the dynamic quick actions for the previously-installed version.
This means that even when the app is closed the system remembers about both kinds of quick actions. While your app is in memory, such as when going into background, the system can still query the UIApplication for the dynamic actions but it must keep some other sort of persistence of quick actions when the app is closed.
I think there is just no guarantee about the point at which the system synchronizes with the dynamic quick actions. My guess is that the system does not necessarily synchronize when closing the app, yours might be an unsupported use case.
With routing/routes defined in the manifest.json and using Router.navTo() to change the hash and the content of the target App control, I noticed that the "old" views and controllers are still hanging around and listening to events (e.g. performing binding updates for controls that are no longer visible on the stage).
I (wrongly) assumed that the router would clean these views/controls up for me - what is the recommended way doing so?
You are correct. Before calling oRouter.navTo(...) you can call unbind. To give you an example you could check here. There you can find the following line of code inside the onNavBack handler:
this.getView().unbindElement();
unbindElement() is called because previously bindElement(...) was called in the same controller. So just make sure to use bind/unbind combination before oRouter.navTo()...
I'm trying to minimize memory usage in my app, and one of the things I'm doing is calling finish() in the onPause method (which I know is not the best way to do things). For the most part, it seems to be working well, but when the user clicks the back button from the next activity, it logically skips over the finished activity and goes back further. Is it possible to have that activity in the back stack and just get recreated if the user presses back?
No. This conclusion comes from the task and backstack documentation as well as the activity documentation and a general understanding of how a stack data structure works.
A stack data strucure only has 2 possible operations push/put, which adds something to the collection, and pop, which removes it. Stacks folow a last in first out model, or LIFO, where by last thing added - in your case an activity - is the first thing removed when pop is called.
Within the android lifecycle activities are generally popped from the stack when the back button is pressed. At that point onDestroy() is called and the activity is removed (you can verify this by overriding the onDestroy() method and logging the results if you want to check). Alternativly you can force onDestroy() to be called by calling finish() as you are. Finishing an activity effectivly does the same thing as pressing back. The activity is destroyed and must be recreated before it can be added to the stack.
For what you're trying to do the stack would have to incorporate some intermediate state in which an activity does not exist but rather something akin to a reference is held that, when moved to the top, would indicate that the corresponding activity should be recreated. Since this is not how the sack works - it only holds activities - that state cannont exist and so the result you are talking about is not possible.
Your Goal is to minimize memory usage,Just make use of activity life cycle, You can do this alternative(if you need)
-Just leave onCreate() method blank.(only do setContentView(layout))
-Override onResume();
-whatever you were doing in onCreate just copy paste to onResume().
-and In onPause(), Recycle your all bitmaps and set them to null(I think you are using Bitmaps thats why you are very cautious about it ). and remove your views.
Now what will happen, when you launch your new activity, onPause() would be called. that will remove your all bitmap and views. and when you come back, onResume() will be call.(onCreate will not be called). and that will again initialize your view and bitmaps.
No, i don't think that is possible. Once you finish the Activity it's gone. You could, however, implement and handle your own stack. On back pressed, you would just start the closed Activity again.
I'm automating an app that shows some overlay messages anywhere on the app for several scenarios, such as app installed for the first time etc. (I'm fairly new to Robotium too.)
The overlay displays a text that goes away by swiping or clicking on it. Also, there are different types of these overlays with different unique text on it. (let's call it Activity A)
I wanted to create a robust test case that handles this case gracefully. From the test's perspective we won't know that the activity A will be present all the time. But I want to recover from the scenario if it does, by writing a method that I can call any time. Currently, the tearDown method gets called since my expected activity name doesn't match.
Also, even if the activity A exists, there are other predefined overlay texts too. So, if I use solo.waitForText("abc") to check for text "abc", I may see the overlay 2 with the text "pqr" instead.
So I was looking for a way to automate this, and I can't use solo.assertCurrentActivity() or solo.waitForActivity methods as they just stop the execution after the first failure.
So any guidance is appreciated!
All the waitFor methods return a boolean. So you can use waitForActivity() exactly as you want to. If the Activity doesn't exist it will return false.
You can check which Activity is current:
Activity current = solo.getCurrentActivity();
I am working on a large (>30k lines) event-driven app. I have a sequence of inputs that produces a bug. What I want to do is to break as soon as the final input enters my code.
Is there a general way to do that?
I understand that for any specific sequence of inputs, I can find out where that last input is going to enter my code, then set a breakpoint there. What I would like to do is take out the step of "find out where that last input enters my code." In other words, I am running the app in the simulator, and I want to set a flag somewhere that says "break the next time you are going to enter non-system Objective C code." Then I send the event that causes the problem.
I understand what you are asking, but have you tried using an Exception Breakpoint? This will basically act like an auto-inserted breakpoint on the piece of code that throws the exception. If that doesn't work for you, try a symbolic breakpoint
If you want to intercept UI events, you can try subclassing UIWindow and overriding its sendEvent: method, then setting this class as the class of the UIWindow object in your main XIB file. sendEvent: will be called each time the user generates a touch event. Unfortunately, at this point you cannot yet know which UI object will finally consume the event (read: which event handler code will be ultimately called) since that depends on the actual state of the responder chain. But anyway, you can use this method to inject events into the system.