Загрузите файл во временную папку в Swift 4 (ОС Ma c), как с помощью curl - PullRequest
2 голосов
/ 14 марта 2020

Я пишу инструмент CLI в Swift 4 для MacOS. Если я «обманываю» и использую функцию оболочки, то при помощи команды curl я получаю именно тот результат, который мне нужен:

func shell(_ args: String...) -> Int32 {
    let task = Process()
    task.launchPath = "/usr/bin/env"
    task.arguments = args
    task.launch()
    task.waitUntilExit()
    return task.terminationStatus
}

shell("/usr/bin/curl", "-OL", "http://mywebserver/myfile.whatever")

Как мне сделать то же самое изначально в Swift 4? Я попытался использовать только библиотеку: https://github.com/dduan/Just, но я не могу понять, как просто заставить его загрузить файл с URL-адреса в указанное c расположение в файловой системе. Я также нашел различные решения для Swift 3 и 5 и iOS, которые, очевидно, не работают для меня.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Простой пример: из-за асинхронного поведения URLSession вы должны запустить runl oop после возобновления задачи с данными и остановить ее в обработчике завершения.

let runLoop = CFRunLoopGetCurrent()
let url = URL(string: "http://mywebserver/myfile.whatever")!

let dataTask = URLSession.shared.dataTask(with: url) { data, response, error in
    let returnValue : Int32
    if let error = error {
        fputs("\(error.localizedDescription)\n", stderr)
        returnValue = EXIT_FAILURE
    } else {
        let result = String(data:data!, encoding:.utf8)!
        fputs("\(result)\n", stdout)
        returnValue = EXIT_SUCCESS
    }
    CFRunLoopStop(runLoop)
    exit(returnValue)
}

dataTask.resume()
CFRunLoopRun()

Код возвращает данные в стандартный вывод. Вы можете записать данные непосредственно на диск, заменив

let result = String(data:data!, encoding:.utf8)!
fputs("\(result)\n", stdout)

на

 let fileURL = URL(fileURLWithPath: "/Users/me/path/to/file.ext")
 do {
    try data!.write(to: fileURL)
 } catch { 
   fputs("\(error.localizedDescription)\n", stderr)
 }
0 голосов
/ 19 марта 2020

Вы можете загрузить, используя downloadTask

  1. Создать конфигурацию сеанса
  2. Создать URLSession с этой конфигурацией
  3. Применить задачу загрузки
  4. Когда загрузка выполнена успешно, скопируйте данные в пункт назначения
let documentsUrl:URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg")

    //Create URL to the source file you want to download
let fileURL = URL(string: "https://en.wikipedia.org/wiki/Saint_Martin#/media/File:Saint_martin_map.PNG")

    let sessionConfig = URLSessionConfiguration.default
    let session = URLSession(configuration: sessionConfig)

    let request = URLRequest(url:fileURL!)

    let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
        if let tempLocalUrl = tempLocalUrl, error == nil {
            // Success
            if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                print("Successfully downloaded. Status code: \(statusCode)")
            }

            do {
                try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
            } catch (let writeError) {
                print("Error creating a file \(destinationFileUrl) : \(writeError)")
            }

        } else {
            print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
        }
    }
    task.resume()

  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...