I'm not sure how to efficiently capture the screen on a pixel-dense iOS device such as the iPad 3 (2048x1536). I've seen some examples such as this & this:
However, these solutions are too slow. I would like the view to be periodically captured maybe a few times a second, but the capturing mechanism is slow enough that if I executed this in the main thread, the UI would lock up. I was wondering whether it's possible to somehow delegate this to a background thread? Or perhaps there's a more efficient view capturing function? Thanks in advance.
Related
My iOS app launch screen takes about 3 - 5 seconds. I have a map that will load after the launch screen. My users have to wait for the launch screen to load and then wait another 3 seconds for the map to load.
Is there a way to minimize launch screen time?
Basically this delay means that you are doing something very wrong during launch. Your job is to launch immediately. Indeed, the WatchDog app will kill you dead if you don't.
There are excellent WWDC videos on this topic, and you should watch them. But in general there are two ways to go wrong:
You must do nothing time-consuming on the main thread. If you have a time-consuming thing to do, like loading your map or networking, you must do that on a background thread. You need to get out of the way so that the runtime can launch your app now.
Just the other way around, you must not touch the interface on any other thread but the main thread. Doing this wrong causes just the kind of delay you are reporting. Do your work on a background thread, but then get back on the main thread to talk to your views, view controllers, etc.
Finally, I should point out that you might be able to get some idea what you're doing wrong by using Instruments. Unfortunately it works rather badly against app launch, but it can be worth a try. Above all, watch those videos!
It seems that the api replaceCurrentItemWithPlayerItem: will stuck the main thread for some seconds, I understand that replacing the item need the information of the new item which might take some time to preload. But questions come up that why replaceCurrentItemWithPlayerItem: with a nil item object would also stuck the main thread?? It happens to me that sometimes it take more than 5 seconds to replace a nil playerItem.
I wonder what can I do to avoid the issue. Thanks for any advices!
I came across a similar blocking UI thread issue when I used UICollectionView to display and preview video in local photo library via ALAssetLibrary.
The scroll on switching videos is not smoothly,so I guess some method block UI thread.Then I use Core Animation of Instruments to analyze what exactly occupy the UI thread.In Time Profiler I found out that replaceCurrentItemWithPlayerItem need about 30ms to execute in main thread,which is more than 16ms (1000/60(fps)) result in choppy scrolling.
To solve the problem,first I tried that put replaceCurrentItemWithPlayerItem in to background thread using GCD,but It not work.I'm not sure if it is because the Cocoa itself need update UI when call replaceCurrentItemWithPlayerItem,which means the UI thread is still block.Finally I made it work by putting replaceCurrentItemWithPlayerItem at the scrolling end (the delegate func scrollViewDidEndDecelerating(scrollView: UIScrollView)).Now the scrolling is smoothly,yep!
Therefore,my advice is obvious : Using Instruments to analyse what exactly occupy the UI thread
I've got an app which stores images taken by the camera in a table view. I have a problem where the images (using apple's queuing system for memory management) are not able to load as fast as the user can scroll (it stops then jumps when the image loads) and sometimes the app crashes. This is on an iPod 5. I understand that this is because of the fact it cannot load the images quickly enough. Does anybody have any suggestions for how to do this? I know it can be done because of the existence of the music app and such.
Thanks.
Check out this great tutorial.
http://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
It uses NSOperation to achieve your goal.
Load images in background thread. You can use Dispatch_async or NSOperationQueue to get images in background. Your main thread will continue executing UI events.
How would I constantly refresh a background image of my UIImageView, while also still listening for touches and input? What I am looking for is the iOS Objective C equivalent (in java) of creating a new thread apart from the main thread, and having that thread be devoted to updating the background picture as fast as possible. Thanks!
It depends on where the new images are coming from. If they are a cycle of known existing images in your app bundle, just make this an animated image view (or an animated image) and the cycle will happen automatically.
If you need to run code e.g. to get out to the network periodically, then just start a repeating NSTimer. It calls you on the main thread, but your main thread code will be very brief indeed, and networking takes place asynchronously (unless you mess that up deliberately). Just make sure that when you actually set the image, you step out to the main thread, as you must never touch the interface in any way except on the main thread.
I have an app that generates a PDF and displays it at the same time. As expected, there is about a 2-second delay between pressing the "Generate PDF" button and the QLPreviewController presenting the document. Not only that, it appears as though the document fades in momentarily, freezes, and then completes the fade-in.
I understand that the reason for the delay is because it is generating the PDF first, but the design of the application doesn't allow for any other mechanism. I was hoping to put a brief "LOADING..." animation before the QLPreviewController view appears, but everything I've tried so far still presents a 2-second delay.
Can anyone provide guidance on what I might be able to do here?
There are lots of options. I'd suggest that whatever you do, it be asynchronous. This will allow for the UI to not 'freeze' and you can put a loading screen up even if it is for 2 seconds.
There are many ways to implement this. Some involve actual background threads and others don't.
You can use, delegates, NSNotifications, blocks, NSOperations, and/or Grand Central Dispatch.
Here's a tutorial on how to use Grand Central Dispatch
Here's a tutorial on blocks