-3

I have GIF File which is 2MB but when I use celluar and my high speed is over I have 15kb/s and I have to wait certain amount of time to continue using the app..

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        getGif()

}

func getGif(){
    dispatch_async(dispatch_get_main_queue(), {
        do{
            if let json = try NSJSONSerialization.JSONObjectWithData(NSData(contentsOfURL: NSURL(string: "http://google.bg/gif.php")!)!, options: .MutableContainers) as? NSArray{
                self.gifUrl = json[0]["url"] as! String
                self.theGif.image = UIImage.gifWithURL(self.gifUrl)
            }
        }catch{}
    })
}

dispatch doesn't work...

How to continue using the app while the image is loading ?

rickster
  • 124,678
  • 26
  • 272
  • 326
Bogdan Bogdanov
  • 882
  • 11
  • 36
  • 79
  • 1
    Use NSURLSession to download your data. Starter tip here: http://stackoverflow.com/a/35358750/2227743 – Eric Aya Mar 08 '16 at 19:54
  • Agree with Eric, don't use `NSData`'s `contentsOfURL`, it blocks the main thread. – JAL Mar 08 '16 at 19:57

3 Answers3

2

Get off the main thread to perform the download and then get on the main thread to talk to the interface:

func getGif(){
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)), {
        do{
            if let json = try NSJSONSerialization.JSONObjectWithData(NSData(contentsOfURL: NSURL(string: "http://google.bg/gif.php")!)!, options: .MutableContainers) as? NSArray{
                dispatch_async(dispatch_get_main_queue(), {
                    self.gifUrl = json[0]["url"] as! String
                    self.theGif.image = UIImage.gifWithURL(self.gifUrl)
                }
            }
        }catch{}
    })
}

However, it would be better, as you've been told, to do a proper download with NSURLSession.

matt
  • 515,959
  • 87
  • 875
  • 1,141
1
extension UIImage {
    public class func gifWithURL(gifUrl:String, completion: (data: NSData)->()) {
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(NSURL(string: gifUrl)!) { (data, response, error) in
            if error == nil {
                dispatch_async(dispatch_get_main_queue(), {
                completion(data: data!)
                })
            }
        }
        task.resume()
    }
}
Bogdan Bogdanov
  • 882
  • 11
  • 36
  • 79
  • It's a correct approach, but now the gif can't be displayed when I receive the data :D I use https://github.com/bahlo/SwiftGif – Bogdan Bogdanov Mar 08 '16 at 20:23
  • I don't see where you've adopted the above code in your github project. – matt Mar 08 '16 at 20:29
  • It was displayed with a lot of delay, but in completion handler I receive print("complete") maybe 10-20 seconds after I receive the data – Bogdan Bogdanov Mar 08 '16 at 20:29
  • This is not my git I use only the GIF Library... try to run it with my answer and the following code: UIImage.gifWithURL(self.gifUrl, completion: { (data) -> Void in self.theGif.image = UIImage(data: data) }) – Bogdan Bogdanov Mar 08 '16 at 20:34
  • It's gonna load it, but with BIG DELAY doesn't matter that the completionHandler sends the data immediately – Bogdan Bogdanov Mar 08 '16 at 20:37
  • How big is the gif? If it's so big that it takes a long time to download it, it's probably too big to display on an iOS device anyway. Try this on a device; it will probably crash with an out-of-memory error. – matt Mar 08 '16 at 20:42
  • it's 1.5MB, but doesn't matter when I'm on a Wi-Fi and I use the code in the Question it takes about 1-2 secs, but the app stucks again for these seconds. I've tried on my iPhone 6 and the simulator.. The conclusion is that NSURLSession slows the data which will be shown – Bogdan Bogdanov Mar 08 '16 at 20:44
  • Try wrapping `completion(data: data!)` in a `dispatch_async(dispatch_get_main_queue())`. – matt Mar 08 '16 at 20:47
  • yesss now it's WORKSSS THANK YOU, you helped me a lot not ONLY with this question, but with others can you give me some contact with you I want in the future when I will be rich to send you money or hire you to work for me :) check this out https://itunes.apple.com/us/developer/bogdan-bogdanov/id830569441 – Bogdan Bogdanov Mar 08 '16 at 20:51
0

You are using dispatch_async on the main queue so that code is executed on the main thread.

Try dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) instead.

Also there are some nice libraries that hides GCD complexity like Async. And if you need more info on GCD itself feel free to look at the Apple Doc

apouche
  • 9,703
  • 6
  • 40
  • 45