iOS Core Data sometimes is delayed in loading - ios

I have an app that's been available in the app store for a few years that uses Core Data. When the app is launched, the user is taken to the app's home screen where a few buttons are shown. Clicking any of the buttons takes the user to another screen that shows data that is loaded from Core Data in a UITableView (each button takes the user to different data). This is basic functionality that's been working in my app just fine the entire time the app's been available.
At some point last year, I noticed that at random times, the data saved in the app sometimes wouldn't load right away. The first time this happened, I clicked one of the buttons and was taken to a blank screen. I went back to the home screen and tried other buttons, and each screen was blank, so I thought all of my data had been wiped somehow. I proceeded to head back to the home screen and just sat there thinking for about 15 seconds, then I clicked one of the buttons again, but this time the data appeared. All of the other screens had data now as well.
I haven't updated the app in quite a while, so my code is unchanged. I don't recall there being a new iOS release around the time I started observing the issue, but it's possible.
This has happened a few more times since I first discovered it (3 or 4 times total over the last 6 months), but there seems to be no pattern at all. Once the data finally loads during these situations, it always loads right away from that point forward. This has made it impossible for me to debug it, because I can't force this situation to happen (99% of the time the data loads immediately).
Has anyone encountered this before, or have any recommendations on how to proceed? I've witnessed this on the Simulator and once on an actual device.

Random delays in updating your UI are a classic sign of attempting to update the UI from outside the main queue. It'll work, usually, but it may be delayed, and the delays won't be consistent. Make sure that when you try to update the UI, you're on the main queue. Use DispatchQueue.main.async() if necessary.
Assuming that you're using Xcode 9, make sure the main thread checker is turned on. That'll help you find this kind of problem when you're running the app from Xcode. Go to the target pop-up at the top of Xcode's window and select "Edit scheme...". In the "Run" section of the window, go to "Diagnostics" and make sure "Main Thread Checker" is turned on.

Related

Launch Screen takes too long to disappear

I just started learning Swift. It's been only a month, and I can assure you that I'm not doing anything fancy. Yet, the launch screen on the simulator is taking a long time to disappear before the app starts. It stays on for at least 5 seconds, and it takes another 2.5 seconds to slowly fade away. And as it fades out, the first view of the app slowly fades in. It was working fine (took only a fraction of a second) until a couple of days ago when this started happening suddenly while I was working on a sample app. Here are things I've confirmed:
During the initial 5 seconds, the app won't accept any user interaction. But during the 2.5 seconds of fading, it responds to touches.
This is a systematic problem because ALL sample code shows the same problem.
Even a new project, without any modifications, shows the same problem. I tried both "Game" and "Single View Application". After the name of the project is displayed as a launch screen, it takes about 8 seconds for the "Hello World" to appear completely. (When "Game" is selected.)
Restarting Xcode and rebooting the Mac do not help.
Updating to Xcode (6.4) does not help. My Xcode was 6.3.x (I believe it was 6.3.2 before the update).
Reinstalling a new copy does not help. I deleted the newly updated 6.4, and re-installed a new copy of 6.4.
The only similar incident I could find was this link, which did not provide the answer.
I was working on a simple practice program. It ran successfully just like it did numerous times before. Then, I made some minor changes to the code (nothing fancy --- just some trivial changes.) And the next time I pressed the RUN button, I noticed that the launch screen took a considerably longer to disappear. After that, it just won't go back to the way it was.
Could someone please advise the cause of the problem and the solution? Thank you very much.
You may have Slow Animations turned on. Go to the simulation and check under Debug:

iPhone SDK - possible to have multiple splash screens?

I'm making an app with a different screen for its first run. Once it has completed its first run, this screen is never shown again. The issue I have is that my launch image is built to look like the view that the user sees every other time they run the app, so at first run the loading screen looks weird. Is there any way to have one loading screen for first run and one loading screen for other runs? Thanks
You cannot have multiple or dynamic launch images. Even with the new storyboard/nib launch files, they are still quite static.
Make sure to open an enhancement report with Apple, requesting this feature.
In the meantime, consider a slight change of your flow to first display the initial view, and have an animation to display your first-launch view. This way, the transition will be smoother and more natural to your users.

UITableView freezes after deleting an entry

My app's MasterView includes a table view which is filled with 10 cells containing some core data objects like a "title" (previously downloaded from the internet, see next paragraph). Thanks to the template "Master-Detail Application" I can make use of the built-in NSFetchedResultsController and its methods which take care of the core data handling (e.g. deleting rows). When running the app, the cells get configured with the existent core data objects. At this point I can delete those entries like one would expect.
In addition, my app also has a refresh button. When tapped, it loads some new data from the internet and converts it into objects that are saved to core data. The cells configure themselves again the same way they did before and the UITableView gets a refresh. Again I can delete an entry but now, as soon as I've deleted one which then disappears normally, the table freezes (not the whole app) in the sense that its cells are not tappable anymore/don't react to gestures. I can refresh and that work (10 entries again after having deleted one before) but the cells keep being untappable. I have to stop the app to return to normal functionality.
When restarting, the one entry deleted before is - like expected - gone, 9 entries are left. Again everything works fine at this point, I can delete multiple ones without a problem. But as soon as a manual refresh took place, we're at the same point as before when deleting an entry now.
A common pattern when missing something specific? I'm happy to post some code but I have no idea right now which parts would help...
If the app is really freezing, common sources of this sort of problem are deadlocks. If you're using dispatch_sync anywhere, that's a common source of problems (notably using dispatch_sync from the main thread to something that eventually does another dispatch_sync back to the main thread). If you're using NSLock or #synchronized, and call them recursively, you can also deadlock that way, too.
Another source of problem is an infinite loop (such as an error in a while clause that is never satisfied). If you have such a loop in the main thread, that will freeze the UI. (Anything that blocks the main thread will freeze the UI.)
You might be able to diagnose where it's freezing by running the app through the debugger in Xcode, and when the app freezes, press the debugger's "pause" button. While it will often pause in the middle of some fairly cryptic assembler code, you can often look at the stack traces to figure out where the app was when it froze.
If it's simply that you're not seeing your UI updated as a result of your actions, try making sure that the reloadData method is called on the main queue, if it's not, e.g.:
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
Not sure if related, but I run into a freezing problem with table view with header and footer view that were reloaded manually after Core Data fetch request. Table view was reloaded right after the fetch and sometimes was stopping respond to touches. Delaying the tableView.reloadData() by 0.1 second fixed the problem completely.
(Without header and footer view, everything worked fine).

iPhone app Debug Is very fast but (Adhoc and appstore) Release is very slow

Does anyone know of any potential causes of chuggy slowness through out an iPhone app, as a result of some kind of config or third party library in the release version of an app?
I have libTestFlight, libGoogleAnalytics, libBlitFeedback, MKNetwork as well as Bolts, NewRelic, Parse and the Facebook SDK... everything else is a standard iOS SDK library.
When I build for Debug, she runs lightning fast... I simply change to 'archive' and release the app on test flight and walah it runs like a piece of crap.
I use images heavily which are all generally loaded by using "UIImageView+WebCache.h" and the SDWebImage package https://github.com/rs/SDWebImage.
I'm just in the process of elimation at the moment as the app never used to run chuggy, but I made a lot of changes in the space of a week which were all intended to make the app smoother and faster.
An example use case is:
User opens App.
Table View loads cells with images and text.
Network call updates data.
User taps tab bar to change to a UICollectionViewController. It reloads.
User taps Profile VC, it refreshes some data.
In Debug... this use case is lightnining fast, transitions smooth and quick on iPhone 4 or 5
In Release mode.. Tapping on the tab bar takes 3 seconds to transition. Scrolling is clunky in the tableview or collection view.
In answer to my own question, the reason was the result of dropping this particular piece of code in my release target.
https://gist.github.com/steipete/5664345
And more precisely this piece of code #define PROPERTY(propName) ##propName:
// Compile-time selector checks.
if DEBUG
define PROPERTY(propName) NSStringFromSelector(#selector(propName))
else
define PROPERTY(propName) ##propName
endif
Was found to be the cause of our problems only discovered by using profiler and realising that it was just soaking up the available CPU cycles. iPhone 4 was so slow it basically was unresponsive.
Anyway, the generic answer is to profile your app to see whats slowing the CPU down.

Screenshot that taken by iOS when (before) application go into background?

I hope that you all know about it, iOS takes screenshot before your application goes to background.
I got it from official document.
Remove sensitive information from views before moving to the background: When an app transitions to the background, the system takes a snapshot of the app’s main window, which it then presents briefly when transitioning your app back to the foreground. Before returning from your applicationDidEnterBackground: method, you should hide or obscure passwords and other sensitive personal information that might be captured as part of the snapshot.
So, Here We can hide our "sensitive personal information" and the system takes a snapshot of the app’s main window, so we can not change its feature.
But I want to know..
1) If in my application I'm at 4th View, and my app goes to background then system takes screen shot of which view/page? first one (start up view of apps?) or 4th view/page of the app ?? (here is little confusion for me).
2) Can we fire any action when system is taking screenshot or any notification is available that will inform us of system taking screenshot ??
3) I just want to know, is it possible to take screen shot (programmatically) before my application launch ?? If YES then give me suggestion for how to do it. And if NO then where/when I'm able to take screenshot (I mean at which minimum stage of application we'll be able to take screenshot ?) ?
It will take a screen short of the top most view, actually it is taking a screen shot of the window which is displaying your app.
No there is no notification that the screen shot is going to or being taken. You should just handle the handle it in the applicationDidEnterBackground; method. Just a stated in the documentation
No this is not possible, how do you want to execute any code before you app is running? The OS will make the screen shot, just be sure to have everything hidden in the applicationDidEnterBackground;. The minimum state is that your app is up and running.
What I've done is on of my apps is as soon as my app gets pushed to the background place an extra view on my UIWindow. Thus when the screen shot is made this view is captured.
1) There is just one screen. The screenshot is taken of that screen. In your model case that should be the 4th view controller's view. However, it is quite possible that your 4th controller's view does not cover all of the screen or has transparent elements. In that case parts of the 3rd or even 2nd and 1st view controller's view are part of the screen.
It is a screenshot not a view controller shot or anything.
2) You understood the documentation all right. The screenshot is taken after you returned from applicationDidEnterBackground. There will be no further dokumentation.
3) No, you cannot execute any code before your app is invoked. However, I have the feeling that you are looking for something different than you asked literally.
For some other reason I have executed a small program in the simulator by implementing the main function only even without calling UIApplicatoinMain. This is the first point in time where code from your app may be executed, although that would not be exactly "out of the book". If I remember right, the screen was blank/black at that point in time. So if you are asking for a way of creating screenshots of other apps, this is not the way to go forward.
It is not taking a screenshot quite like a user pressing buttons.
This functionality is related to state restoration. When the application goes to the background it flattens the view hierarchy for each screen into a screenshot used for the task manager. If you are opted into state restoration it will also persist the state of the user interface. This means that a person can bring the application back from the background state and potentially see sensitive information that way as well, which may be something you need to handle.
Preventing information from being included in the state screenshot is covered in Tech QA 1838.
1) I'm pretty sure the system will take the snapshot of the current visible view, so the last one on the stack, not the first one
2) Also, there will probably be a Notification to let us know that the system is going to take a screenshot (otherwise how can we hide sensible information? :) ), but I'm afraid we're currently under NDA I guess?
3) What do you mean "take screenshot before my application launch"? Your code starts executing when your application launches, so this question almost makes no sense :-/
You can anywhere in your application take a snapshot of the screen, however, and there are many stackoverflow posts for that

Resources