Как в Swift 4.2 прочитать содержимое текстового файла по его общей ссылке Dropbox (без загрузки)? - PullRequest
0 голосов
/ 04 августа 2020

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

Например:

let url = URL(string: "https://www.dropbox.com/s/rokwv82h54ogwy1/test.txt?dl=0")!
// the dropbox link above is a shared link so anyone can view it
    
do {
                
    let content = try String(contentsOf: url)
    print("File Content:   \(content)")
} catch let error as NSError {
                
    print("\(error)")
}

Когда я запускаю этот код, я получаю следующую ошибку:

Error Domain = NSCocoaErrorDomain Code = 260 «Не удалось открыть файл test.txt, потому что такого файла нет» *. 1009 * (есть еще ошибка, но она довольно большая)

Кто-нибудь может мне помочь, пожалуйста? Спасибо.

1 Ответ

1 голос
/ 05 августа 2020

Есть еще одна ошибка, но она довольно большая

Не удаляйте сообщения об ошибках. Если вы не знаете, как исправить эту проблему, вы, вероятно, не знаете, что удалять, чтобы сохранить ценность.

Как решить вашу проблему

  • Выберите цель
  • Переключиться на Подписание и возможности вкладка
  • Тестовая среда приложения - Сеть - включить Исходящие соединения (Клиент)

enter image description here

  • Change the URL (dl=0) to (dl=1)
    • 0 = display web page with a preview and download link
    • 1 = do not display any web page, just serve the file
let url = URL(string: "https://www.dropbox.com/s/rokwv82h54ogwy1/test.txt?dl=1")!
// Change dl=0 to dl=1                                                       ^
    
do {
    let content = try String(contentsOf: url)
    print("File Content: \(content)")
} catch let error as NSError {
    print("\(error)")
}

Запустите еще раз, и вы получите:

File Content:   
This is a test. If you can read this, you have passed! :)

Не используйте String(contentsOf: url), потому что это не asyn c, и он заблокирует основной поток (UI).

Асинхронный пример - представьте, что у вас есть контроллер представления с одним текстовым полем (меткой), и вы хотите отобразить там содержимое файла:

import Cocoa

class ViewController: NSViewController {
    @IBOutlet var textField: NSTextField!
    
    override func viewWillAppear() {
        super.viewWillAppear()
        textField.stringValue = "Loading ..."
        loadRemoteFile()
    }
    
    func loadRemoteFile() {
        let url = URL(string: "https://www.dropbox.com/s/rokwv82h54ogwy1/test.txt?dl=1")!
        
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            // Following code is not called on the main thread. If we'd like to
            // modify UI elements, we have to dispatch our code on the main thread.
            // Hence the DispatchQueue.main.async {}.
            
            if let error = error {
                print("Failed with error: \(error)")
                DispatchQueue.main.async { self.textField.stringValue = "Failed" }
                return
            }

            guard let data = data,
                  let content = String(data: data, encoding: .utf8) else {
                print("Failed to decode data as an UTF-8 string")
                DispatchQueue.main.async { self.textField.stringValue = "Failed" }
                return
            }
            
            print("Content: \(content)")
            DispatchQueue.main.async { self.textField.stringValue = content }
        }
        
        // At this point, we have a task which will download the file, but the task
        // is not running. Every task is initially suspended.
        
        task.resume() // Start the background task
        
        // At this point, your program normally continues, because the download
        // is executed in the background (not on the main thread).
    }
}
...