Попытка загрузить изображения в фоновом потоке вместо основного потока в iOS с помощью Swift [duplicate]

Если вы хотите проверить, существует ли программа и действительно ли это программа, а не встроенная команда bash, тогда command, type и hash не подходят для тестирования, поскольку все они возвращают 0 выход статус для встроенных команд.

Например, есть программа времени, которая предлагает больше возможностей, чем встроенная команда времени. Чтобы проверить, существует ли программа, я бы предложил использовать which, как в следующем примере:

# first check if the time program exists
timeProg=`which time`
if [ "$timeProg" = "" ]
then
  echo "The time program does not exist on this system."
  exit 1
fi

# invoke the time program
$timeProg --quiet -o result.txt -f "%S %U + p" du -sk ~
echo "Total CPU time: `dc -f result.txt` seconds"
rm result.txt
295
задан Mick MacCallum 2 April 2016 в 17:31
поделиться

24 ответа

Xcode 8 • Swift 3

Синхронно:

if let filePath = Bundle.main.path(forResource: "imageName", ofType: "jpg"), let image = UIImage(contentsOfFile: filePath) {
    imageView.contentMode = .scaleAspectFit
    imageView.image = image
}

Асинхронно:

Создайте метод с обработчиком завершения, чтобы получить данные изображения из вашего url

func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

Создайте способ загрузки изображения (запустите задачу)

func downloadImage(from url: URL) {
    print("Download Started")
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else { return }
        print(response?.suggestedFilename ?? url.lastPathComponent)
        print("Download Finished")
        DispatchQueue.main.async() {
            self.imageView.image = UIImage(data: data)
        }
    }
}

Использование:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    print("Begin of code")
    if let url = URL(string: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") {
        imageView.contentMode = .scaleAspectFit
        downloadImage(from: url)
    }
    print("End of code. The image will continue downloading in the background and it will be loaded when it ends.")
}

Расширение:

extension UIImageView {
    func downloaded(from url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
        contentMode = mode
        URLSession.shared.dataTask(with: url) { data, response, error in
            guard
                let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                let data = data, error == nil,
                let image = UIImage(data: data)
                else { return }
            DispatchQueue.main.async() {
                self.image = image
            }
        }.resume()
    }
    func downloaded(from link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
        guard let url = URL(string: link) else { return }
        downloaded(from: url, contentMode: mode)
    }
}

Использование:

imageView.downloaded(from: "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png")
593
ответ дан Leo Dabus 3 September 2018 в 13:23
поделиться

Swift 2.0:

1)

if let url = NSURL(string: "http://etc...") {
    if let data = NSData(contentsOfURL: url) {
        imageURL.image = UIImage(data: data)
    }        
}

ИЛИ

imageURL.image =
    NSURL(string: "http:// image name...")
    .flatMap { NSData(contentsOfURL: $0) }
    .flatMap { UIImage(data: $0) }

2) Добавьте этот метод в VC или Extension.

func load_image(urlString:String)
{   let imgURL: NSURL = NSURL(string: urlString)!
    let request: NSURLRequest = NSURLRequest(URL: imgURL)

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in

        if error == nil {
            self.image_element.image = UIImage(data: data)
        }
    }
}

Использование:

self.load_image(" url strig here")
5
ответ дан A.G 3 September 2018 в 13:23
поделиться
let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData)
11
ответ дан Anonymous 3 September 2018 в 13:23
поделиться

Способ получения безопасного изображения и работы с Swift 2.0 и X-Code 7.1:

static func imageForImageURLString(imageURLString: String, completion: (image: UIImage?, success: Bool) -> Void) {
    guard let url = NSURL(string: imageURLString),
        let data = NSData(contentsOfURL: url),
        let image = UIImage(data: data)
        else { 
            completion(image: nil, success: false); 
            return 
       }

    completion(image: image, success: true)
}

Затем вы вызываете этот метод следующим образом:

imageForImageURLString(imageString) { (image, success) -> Void in
        if success {
            guard let image = image 
                 else { return } // Error handling here 
            // You now have the image. 
         } else {
            // Error handling here.
        }
    }

Если вы обновляете представление с изображением, вам придется использовать его после «if success {»:

    dispatch_async(dispatch_get_main_queue()) { () -> Void in
         guard let image = image 
              else { return } // Error handling here 
         // You now have the image. Use the image to update the view or anything UI related here
         // Reload the view, so the image appears
    }

. Причина, по которой эта последняя часть необходима, если вы используете изображение в пользовательский интерфейс связан с тем, что сетевые вызовы требуют времени. Если вы попытаетесь обновить пользовательский интерфейс, используя изображение, не вызывая dispatch_async, как показано выше, компьютер будет искать изображение, пока изображение все еще будет извлечено, найдите, что изображения нет (пока), и двигайтесь так, как если бы не было изображения найденный. Поместив свой код в завершение закрытия dispatch_async, он говорит компьютеру: «Идите, получите это изображение, и когда вы закончите, заполните этот код». Таким образом, вы получите изображение, когда код будет вызван, и все будет хорошо работать.

3
ответ дан Ben Patch 3 September 2018 в 13:23
поделиться

Используйте этот код в Swift

imageView.image=UIImage(data: NSData(contentsOfURL: NSURL(string: "http://myURL/ios8.png")!)!
0
ответ дан Bibin Joseph 3 September 2018 в 13:23
поделиться

Swift 4

Этот метод будет загружать изображение с сайта асинхронно и кэшировать его:

    func getImageFromWeb(_ urlString: String, closure: @escaping (UIImage?) -> ()) {
        guard let url = URL(string: urlString) else {
return closure(nil)
        }
        let task = URLSession(configuration: .default).dataTask(with: url) { (data, response, error) in
            guard error == nil else {
                print("error: \(String(describing: error))")
                return closure(nil)
            }
            guard response != nil else {
                print("no response")
                return closure(nil)
            }
            guard data != nil else {
                print("no data")
                return closure(nil)
            }
            DispatchQueue.main.async {
                closure(UIImage(data: data!))
            }
        }; task.resume()
    }

При использовании:

    getImageFromWeb("http://www.apple.com/euro/ios/ios8/a/generic/images/og.png") { (image) in
        if let image = image {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
            imageView.image = image
            self.view.addSubview(imageView)
        } // if you use an Else statement, it will be in background
    }
5
ответ дан Bobby 3 September 2018 в 13:23
поделиться

Swift 2 с ошибкой Ручка и пользовательский заголовок запроса

Просто добавьте расширение в UIImageView:

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSMutableURLRequest(URL: url)
            request.setValue("<YOUR_HEADER_VALUE>", forHTTPHeaderField: "<YOUR_HEADER_KEY>")
            NSURLSession.sharedSession().dataTaskWithRequest(request) {
                (data, response, error) in
                guard let data = data where error == nil else{
                    NSLog("Image download error: \(error)")
                    return
                }

                if let httpResponse = response as? NSHTTPURLResponse{
                    if httpResponse.statusCode > 400 {
                        let errorMsg = NSString(data: data, encoding: NSUTF8StringEncoding)
                        NSLog("Image download error, statusCode: \(httpResponse.statusCode), error: \(errorMsg!)")
                        return
                    }
                }

            dispatch_async(dispatch_get_main_queue(), {
                NSLog("Image download success")
                self.image = UIImage(data: data)
            })
            }.resume()
        }
    }
}

И затем используйте новый imageFromUrl(urlString: String) для загрузки изображения

Использование:

imageView.imageFromUrl("https://i.imgur.com/ONaprQV.png")
7
ответ дан Cody 3 September 2018 в 13:23
поделиться

Swift 2.x ответ, который загружает изображение в файл (в отличие от ответа Лео Дабуса, в котором хранится изображение в памяти). На основании ответа Льва Дабуса и ответа Роба из Получить данные из NSURLSession DownloadTaskWithRequest из обработчика завершения :

    // Set download vars
    let downloadURL = NSURL() // URL to download from
    let localFilename = "foobar.png" // Filename for storing locally 

    // Create download request
    let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in
        guard location != nil && error == nil else {
            print("Error downloading message: \(error)")
            return
        }

        // If here, no errors so save message to permanent location
        let fileManager = NSFileManager.defaultManager()
        do {
            let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            let fileURL = documents.URLByAppendingPathComponent(localFilename)
            try fileManager.moveItemAtURL(location!, toURL: fileURL)
            self.doFileDownloaded(fileURL, localFilename: localFilename)
            print("Downloaded message @ \(localFilename)")
        } catch {
            print("Error downloading message: \(error)")
        }
    }

    // Start download
    print("Starting download @ \(downloadURL)")
    task.resume()


// Helper function called after file successfully downloaded
private func doFileDownloaded(fileURL: NSURL, localFilename: String) {

    // Do stuff with downloaded image

}
1
ответ дан Community 3 September 2018 в 13:23
поделиться

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

Здесь это мой класс:

import Foundation
import UIKit

class UIImageViewAsync :UIImageView
{

    override init()
    {
        super.init(frame: CGRect())
    }

    override init(frame:CGRect)
    {
        super.init(frame:frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func getDataFromUrl(url:String, completion: ((data: NSData?) -> Void)) {
        NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: url)!) { (data, response, error) in
            completion(data: NSData(data: data))
        }.resume()
    }

    func downloadImage(url:String){
        getDataFromUrl(url) { data in
            dispatch_async(dispatch_get_main_queue()) {
                self.contentMode = UIViewContentMode.ScaleAspectFill
                self.image = UIImage(data: data!)
            }
        }
    }
}

и вот как его использовать:

imageView.downloadImage("http://www.image-server.com/myImage.jpg")
14
ответ дан datayeah 3 September 2018 в 13:23
поделиться

Для Swift-3 и выше:

extension UIImageView {
  public func imageFromUrl(urlString: String) {
    if let url = URL(string: urlString) {
        let request = URLRequest(url: url)
        NSURLConnection.sendAsynchronousRequest(request as URLRequest, queue: .main, completionHandler: { (response, data, error) in
            if let imageData = data as NSData? {
                self.image = UIImage(data: imageData as Data)
            }
        })
    }
  }
}
-1
ответ дан FARAZ 3 September 2018 в 13:23
поделиться

Xcode 8 • Swift 3

Ответ Leo Dabus является потрясающим! Я просто хотел предоставить решение «все-в-одном»:

let url = URL(string: 
    "http://www.apple.com/euro/ios/ios8/a/generic/images/og.png")

let task = URLSession.shared.dataTask(with: url!) { data, response, error in
    guard let data = data, error == nil else { return }

    DispatchQueue.main.async() {    // execute on main thread
        self.imageView.image = UIImage(data: data)
    }
}

task.resume()
23
ответ дан Frédéric Adda 3 September 2018 в 13:23
поделиться

Swift 4.1 У меня есть функция, которая просто передаёт URL-адрес изображения, кэш-ключ после создания изображения устанавливает его в блок завершения.

   class NetworkManager: NSObject {

  private var imageQueue = OperationQueue()
  private var imageCache = NSCache<AnyObject, AnyObject>()

  func downloadImageWithUrl(imageUrl: String, cacheKey: String, completionBlock: @escaping (_ image: UIImage?)-> Void) {

    let downloadedImage = imageCache.object(forKey: cacheKey as AnyObject)
    if let  _ = downloadedImage as? UIImage {
      completionBlock(downloadedImage as? UIImage)
    } else {
      let blockOperation = BlockOperation()
      blockOperation.addExecutionBlock({
        let url = URL(string: imageUrl)
        do {
          let data = try Data(contentsOf: url!)
          let newImage = UIImage(data: data)
          if newImage != nil {
            self.imageCache.setObject(newImage!, forKey: cacheKey as AnyObject)
            self.runOnMainThread {
              completionBlock(newImage)
            }
          } else {
            completionBlock(nil)
          }
        } catch {
          completionBlock(nil)
        }
      })
      self.imageQueue.addOperation(blockOperation)
      blockOperation.completionBlock = {
        print("Image downloaded \(cacheKey)")
      }
    }
  }
}
extension NetworkManager {
  fileprivate func runOnMainThread(block:@escaping ()->Void) {
    if Thread.isMainThread {
      block()
    } else {
      let mainQueue = OperationQueue.main
      mainQueue.addOperation({
        block()
      })
    }
  }
}
0
ответ дан GSK 3 September 2018 в 13:23
поделиться

Вы хотите сделать:

UIImage(data: data)

В Swift они заменили большинство стандартных методов Objective C на обычные конструкторы.

Смотрите:

https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_26

6
ответ дан joshstaiger 3 September 2018 в 13:23
поделиться

Kingfisher - одна из лучших библиотек для загрузки изображения в URL.

Github URL - https://github.com/onevcat/Kingfisher

// If you want to use Activity Indicator.
imageview_pic.kf.indicatorType = .activity
imageview_pic.kf.setImage(with: URL(string: "Give your url string"))

// If you want to use custom placeholder image.
imageview_pic.kf.setImage(with: URL(string: "Give your url string"), placeholder: UIImage(named: "placeholder image name"), options: nil, progressBlock: nil, completionHandler: nil)
4
ответ дан Kamani Jasmin 3 September 2018 в 13:23
поделиться

FYI: для Swift-2.0 Xcode7.0 beta2

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
            (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
                self.image = UIImage(data: data!)
            }
        }
    }
}
13
ответ дан katopz 3 September 2018 в 13:23
поделиться

(обновление Swift 4) Чтобы ответить на исходный вопрос напрямую, вот быстрый эквивалент опубликованного фрагмента Objective-C.

let url = URL(string: image.url)
let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
imageView.image = UIImage(data: data!)

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ:

важно отметить, что метод Data(contentsOf:) будет загружать содержимое URL синхронно в том же потоке, который выполняется кодом, поэтому не вызывайте его в основном потоке вашего приложения.

Простым способом для того, чтобы один и тот же код выполнялся асинхронно, а не для блокировки пользовательского интерфейса, - это использование GCD:

let url = URL(string: image.url)

DispatchQueue.global().async {
    let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
    DispatchQueue.main.async {
        imageView.image = UIImage(data: data!)
    }
}

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

import Kingfisher

let url = URL(string: "url_of_your_image")
// this downloads the image asynchronously if it's not cached yet
imageView.kf.setImage(with: url) 

И это все

256
ответ дан Lucas Eduardo 3 September 2018 в 13:23
поделиться

swift 3 с обработкой ошибок

let url = URL(string: arr[indexPath.row] as! String)
if url != nil {
    DispatchQueue.global().async {
        let data = try? Data(contentsOf: url!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
        DispatchQueue.main.async {
            if data != nil {
                cell.imgView.image = UIImage(data:data!)
            }else{
                cell.imgView.image = UIImage(named: "default.png")
            }
        }
    }
}

С расширением

extension UIImageView {

    func setCustomImage(_ imgURLString: String?) {
        guard let imageURLString = imgURLString else {
            self.image = UIImage(named: "default.png")
            return
        }
        DispatchQueue.global().async {
            let data = try? Data(contentsOf: URL(string: imageURLString)!)
            DispatchQueue.main.async {
                self.image = data != nil ? UIImage(data: data!) : UIImage(named: "default.png")
            }
        }
    }
}

Использование расширения

myImageView. setCustomImage ( "URL")

7
ответ дан Manee ios 3 September 2018 в 13:23
поделиться

Если вы ищете очень простую реализацию. (Это работало для меня в Swift 2)

 let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")
 let imagedData = NSData(contentsOfURL: imageURL!)!
 imageView?.image = UIImage(data: imagedData)

Я реализовал в представлении таблицы с пользовательской ячейкой, которая имеет только изображение

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

        let cell = tableView.dequeueReusableCellWithIdentifier("theCell", forIndexPath: indexPath) as! customTableViewCell

        let imageURL = NSURL(string: "https://farm2.staticflickr.com/1591/26078338233_d1466b7da2_m.jpg")

        let imagedData = NSData(contentsOfURL: imageURL!)!

        cell.imageView?.image = UIImage(data: imagedData)

        return cell

    }
3
ответ дан Naishta 3 September 2018 в 13:23
поделиться

Вот рабочий код для загрузки / загрузки изображения из URL. NSCache автоматически и отображать изображение заполнителя перед загрузкой и загрузкой фактического изображения (код Swift 4).

func NKPlaceholderImage(image:UIImage?, imageView:UIImageView?,imgUrl:String,compate:@escaping (UIImage?) -> Void){

    if image != nil && imageView != nil {
        imageView!.image = image!
    }

    var urlcatch = imgUrl.replacingOccurrences(of: "/", with: "#")
    let documentpath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    urlcatch = documentpath + "/" + "\(urlcatch)"

    let image = UIImage(contentsOfFile:urlcatch)
    if image != nil && imageView != nil
    {
        imageView!.image = image!
        compate(image)

    }else{

        if let url = URL(string: imgUrl){

            DispatchQueue.global(qos: .background).async {
                () -> Void in
                let imgdata = NSData(contentsOf: url)
                DispatchQueue.main.async {
                    () -> Void in
                    imgdata?.write(toFile: urlcatch, atomically: true)
                    let image = UIImage(contentsOfFile:urlcatch)
                    compate(image)
                    if image != nil  {
                        if imageView != nil  {
                            imageView!.image = image!
                        }
                    }
                }
            }
        }
    }
}

Использовать следующим образом:

// Here imgPicture = your imageView
// UIImage(named: "placeholder") is Display image brfore download and load actual image. 

NKPlaceholderImage(image: UIImage(named: "placeholder"), imageView: imgPicture, imgUrl: "Put Here your server image Url Sting") { (image) in }
0
ответ дан Nikunj Kumbhani 3 September 2018 в 13:23
поделиться

Swift 4: простой загрузчик для небольших изображений (например, миниатюр), который использует NSCache и всегда работает по основному потоку:

class ImageLoader {

  private static let cache = NSCache<NSString, NSData>()

  class func image(for url: URL, completionHandler: @escaping(_ image: UIImage?) -> ()) {

    DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async {

      if let data = self.cache.object(forKey: url.absoluteString as NSString) {
        DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
        return
      }

      guard let data = NSData(contentsOf: url) else {
        DispatchQueue.main.async { completionHandler(nil) }
        return
      }

      self.cache.setObject(data, forKey: url.absoluteString as NSString)
      DispatchQueue.main.async { completionHandler(UIImage(data: data as Data)) }
    }
  }

}

Использование:

ImageLoader.image(for: imageURL) { image in
  self.imageView.image = image
}
5
ответ дан R. Mohan 3 September 2018 в 13:23
поделиться

Использование Ascyimageview вы можете легко загрузить imageurl в imageview.

let image1Url: URL = URL (строка: "(imageurl)" как String)! imageview.imageURL = image1Url

0
ответ дан saurabh rathod 3 September 2018 в 13:23
поделиться

Единственное, чего не хватает, это:!

let url = NSURL.URLWithString("http://live-wallpaper.net/iphone/img/app/i/p/iphone-4s-wallpapers-mobile-backgrounds-dark_2466f886de3472ef1fa968033f1da3e1_raw_1087fae1932cec8837695934b7eb1250_raw.jpg");
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url!,options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var bgImage = UIImage(data:imageData!)
1
ответ дан Simon Jensen 3 September 2018 в 13:23
поделиться

Если вы просто хотите загрузить изображение (асинхронно!) - просто добавьте это небольшое расширение в ваш быстрый код:

extension UIImageView {
    public func imageFromUrl(urlString: String) {
        if let url = NSURL(string: urlString) {
            let request = NSURLRequest(URL: url)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
                (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in
                if let imageData = data as NSData? {
                    self.image = UIImage(data: imageData)
                }
            }
        }
    }
}

И используйте его следующим образом:

myImageView.imageFromUrl("https://robohash.org/123.png")
63
ответ дан skywinder 3 September 2018 в 13:23
поделиться

Swift 2.2 || Xcode 7.3

У меня получились потрясающие результаты !! с быстрой библиотекой AlamofireImage

Он предоставляет множество функций, таких как:

  • Асинхронно скачать
  • Авто-очистка кэша изображений, если для приложения обнаружены предупреждения о памяти
  • Кэширование URL-адреса изображения
  • Кэширование изображений
  • Избегайте дублирования загрузок

и очень легко реализуется для вашего приложения

Шаг.1 Установите контейнеры


Alamofire 3.3.x

pod 'Alamofire'

AlamofireImage 2.4.x

pod 'AlamofireImage'

Шаг 2. Импорт и использование

import Alamofire
import AlamofireImage

let downloadURL = NSURL(string: "http://cdn.sstatic.net/Sites/stackoverflow/company/Img/photos/big/6.jpg?v=f4b7c5fee820")!
imageView.af_setImageWithURL(downloadURL)

вот и все! он позаботится обо всем


Огромное спасибо ребятам из Alamofire , для облегчения жизни iDevelopers;)

38
ответ дан swiftBoy 3 September 2018 в 13:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: