Загрузить изображение с URL-адреса в WatchKit

Есть ли более элегантное решение для загрузки внешнего изображения на часы, чем следующее?

let image_url:String = "http://placehold.it/350x150"

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    let url:NSURL = NSURL(string:image_url)!
    var data:NSData = NSData(contentsOfURL: url)!
    var placeholder = UIImage(data: data)!

    // update ui
    dispatch_async(dispatch_get_main_queue()) {
        self.imageView.setImage(placeholder)
    }
}

person fabian    schedule 05.04.2015    source источник


Ответы (7)


NSURL предназначен для использования с локальными файлами. Вместо этого используйте NSURLSession. Также полезно установить масштаб удаленного изображения.

import WatchKit

public extension WKInterfaceImage {

    public func setImageWithUrl(url:String, scale: CGFloat = 1.0) -> WKInterfaceImage? {

        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { data, response, error in
            if (data != nil && error == nil) {
                let image = UIImage(data: data!, scale: scale)

                dispatch_async(dispatch_get_main_queue()) {
                    self.setImage(image)
                }
            }
        }.resume()

        return self
    }
}

Используйте это так

self.imageView.setImageWithUrl(image_url, scale: 2.0)
person Fokke Zandbergen    schedule 01.12.2015
comment
Это правильный ответ. Изображение не будет отображаться на устройстве, если вы не используете NSURLSession. +1 - person MSU_Bulldog; 01.02.2016

Вот категория

import WatchKit

public extension WKInterfaceImage {

    public func setImageWithUrl(url:String) -> WKInterfaceImage? {

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            let url:NSURL = NSURL(string:url)!
            var data:NSData = NSData(contentsOfURL: url)!
            var placeholder = UIImage(data: data)!

            dispatch_async(dispatch_get_main_queue()) {
                self.setImage(placeholder)
            }
        }

        return self
    }

}

Используйте это так

 self.imageView.setImageWithUrl(image_url)
person fabian    schedule 05.04.2015

Я думаю, что это решение хорошее, потому что оно может помочь вашему приложению избежать отставания, когда вы пытаетесь загрузить некоторые изображения из Интернета. вы можете создать новую функцию следующим образом:

func loadImage(url:String, forImageView: WKInterfaceImage) {
// load image
    let image_url:String = url
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        let url:NSURL = NSURL(string:image_url)!
        var data:NSData = NSData(contentsOfURL: url)!
        var placeholder = UIImage(data: data)!

// update ui
        dispatch_async(dispatch_get_main_queue()) {
            forImageView.setImage(placeholder)
        }
    }

}

после этого в любом месте, где вы хотите загрузить изображение из urlString, вы можете использовать это так:

loadImage("http://...", forImageView: self.myImageView)

Надеюсь, это поможет.

person Hieu Duc Pham    schedule 05.04.2015
comment
Спасибо. Может быть, мы должны сделать это категорией… - person fabian; 05.04.2015
comment
Как добавить обработчик завершения загрузки? - person fabian; 06.04.2015

Я думаю, что с помощью этого решения вы можете хранить изображение в кеше и отображать изображение из кеша, поэтому вы можете вызвать эту функцию и использовать ее.

func loadImage(url:String, forImageView: WKInterfaceImage) {

    forImageView.setImageNamed("placeholder")
    let image_url:String = url

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

        let url:NSURL = NSURL(string:image_url)!
        print(url)

        //if image is already stored in cache
        if WKInterfaceDevice.currentDevice().cachedImages[image_url] != nil{
            dispatch_async(dispatch_get_main_queue()) {
                forImageView.setImageNamed(image_url)
            }
        }else{
            if let data = NSData(contentsOfURL: url){

                //load image
                let image = UIImage(data: data)!
                //Store image in cache
                WKInterfaceDevice.currentDevice().addCachedImage(image, name: image_url)
                dispatch_async(dispatch_get_main_queue()) {
                    forImageView.setImage(placeholder)
                }
            }
        }
    }
}
person vikas prajapati    schedule 27.07.2016

Просто была такая же задача, ответы здесь помогли мне, но мне нужно было внести некоторые изменения. Поэтому я хотел поделиться обновленной версией (без принудительной развертки) общих ответов здесь (должно работать с Swift 4.2):

public extension WKInterfaceImage {

public func setBackgroundImage(url: String) {
    let asyncQueue = DispatchQueue(label: "backgroundImage")
    asyncQueue.async {
        do {
            if let url = URL(string: url) {
                let data = try Data(contentsOf: url)
                if let placeholder = UIImage(data: data) {
                    self.setImage(placeholder)
                }
            }
        } catch let error {
            print("Could not set backgroundImage for WKInterfaceImage: \(error.localizedDescription)")
        }
    }
}

}

person Yasin Mantas    schedule 20.11.2018

     if let url = NSURL(string: "http://google.net/img/upload/photo2.png") {
            if let data = NSData(contentsOfURL: url){

             imageWK.setImage(UIImage(data: data))

        }
    }

Попробуйте этот код. Не забудьте добавить NSTransportSecurity в свой Plist.

person Arvind Kumar    schedule 20.10.2015
comment
Как и другие, это решение отлично работает в симуляторе watchOS для меня, но не на устройстве. После добавления журналов я увидел, что второй оператор if возвращает false. Изображение, которое я использую, если openweathermap.org/img/w/10d.png - person Fokke Zandbergen; 01.12.2015
comment
Вы можете попробовать это для асинхронной загрузки изображений: github.com/natelyman/SwiftImageLoader - person Arvind Kumar; 01.12.2015
comment
Спасибо, я только что добавил еще один ответ, используя NSURLSession, который отлично работает как на симуляторе, так и на устройстве. - person Fokke Zandbergen; 01.12.2015

Свифт 4.2

Используя URLSession, соответствующие GCD и @discardableResult, отключите предупреждение Result of call to '...' is unused.

список
App Transport Security Settings
Allow Arbitrary Loads - YES

Вы можете установить фиксированный размер изображения 100x100 в раскадровке, если хотите.

let url = "https://i.imgur.com/UZbLC0Q.jpg"

public extension WKInterfaceImage {

    @discardableResult public func setImageWithUrl(url:String, scale: CGFloat = 1.0) -> WKInterfaceImage? {

        URLSession.shared.dataTask(with: NSURL(string: url)! as URL) { data, response, error in
            if (data != nil && error == nil) {
                let image = UIImage(data: data!, scale: scale)

                DispatchQueue.main.async {
                    self.setImage(image)
                }
            }
            }.resume()

        return self
    }
}

вызов

row.image.setImageWithUrl(url: url, scale: 1.0)
person Edison    schedule 20.03.2019