Лучший способ загрузить файл .txt? - PullRequest
0 голосов
/ 26 апреля 2018

Я практикуюсь, создавая простое приложение с 20 TXT-файлами, которые я добавил в приложение.Вот что у меня получилось:

  1. Создан tableviewcontroller со встроенной навигацией и подробным представлением
  2. Список заголовков файлов .txt с файловым менеджером в tableview

Я застрял при попытке загрузить файлы .txt в текстовое представление, когда выбрана плитка .txt.Я попытался использовать func load, но затем застрял на том, как вызвать load, когда выбран заголовок .txt.Может кто-нибудь помочь или связать меня с чем-то, что объясняет это?

В идеале я хотел бы добавить файлы .txt таким образом, чтобы обеспечить большую гибкость, чем просто добавление текстовых тел.Это стихи на иностранном языке, и я хотел бы добавлять переводы после каждой строки, которая может включаться и выключаться.Кто-нибудь знает, как я мог это сделать, и если направление, которое я выбрал до сих пор, является лучшим способом добраться туда?Должен ли я вызывать файлы другим способом?

Вот мой контроллер вида:

import UIKit

class ViewController: UITableViewController {
    var hymns = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let fm = FileManager.default
        let path = Bundle.main.resourcePath!
        let items = try! fm.contentsOfDirectory(atPath: path)

        for item in items {
            if item.hasSuffix(".txt") {
                hymns.append(item)
            }
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return hymns.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Hymn", for: indexPath)
        cell.textLabel?.text = hymns[indexPath.row]
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
            vc.selectedHymns = hymns[indexPath.row]
            navigationController?.pushViewController(vc, animated: true)
        }
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

And this is my detailViewController so far:
import UIKit

class DetailViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!

    var selectedHymns: String?
    var hymnText = [String] ()


    override func viewDidLoad() {
        super.viewDidLoad()

        if let textToLoad = selectedHymn {
            if let hymnText = load(file: textToLoad){
            textView.text = hymnText
        }

    }
    }

    func load(file name:String) -> String {
        if let path = Bundle.main.path(forResource: name, ofType: "txt") {
            if let contents = try? String(contentsOfFile: path) {
                return contents
            } else {
                print("Error! - This file doesn't contain any text.")
            }
        } else {
            print("Error! - This file doesn't exist.")
        }
        return ""
    }
}

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Проблема в том, что массив hymns содержит полные строковые пути , и вы собираетесь загрузить содержимое с path(forResource, который ожидает имя файла (последний компонент путипути строки).

Я настоятельно рекомендую всегда использовать API, связанный с URL, и отображать имя файла в ячейке табличного представления.

  • Объявление массива источника данныхв виде массива URL

    var hymns = [URL]()
    
  • В viewDidLoad вы можете заменить код одной строкой

    override func viewDidLoad() {
        super.viewDidLoad()
        hymns = Bundle.main.urls(forResourcesWithExtension: "txt", subdirectory: nil)!
    }
    

    , метод возвращает URL всех файловс указанным расширением в комплекте

  • В cellForRow вы можете отобразить только имя файла

    cell.textLabel?.text = hymns[indexPath.row].lastPathComponent
    

    Вы можете даже удалить расширение

    cell.textLabel?.text = hymns[indexPath.row].deletingPathExtension().lastPathComponent
    
  • В DetailViewController создайте свойство selectedHymn (лучше в единственном числе) как URL

    var selectedHymn : URL!
    
  • Конечно, тогда вынужно изменить строку для отправки URL-адреса в didSelectRowAt в первом контроллере представления на

    vc.selectedHymn = hymns[indexPath.row]
    
  • Теперь у вас есть URL файла, который можно использовать непосредственно для загрузки текста

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let hymnText = try! String(contentsOf: selectedHymn )
        textView.text = hymnText
    }
    

    Метод load(file вообще не нужен.URL-адрес, полученный методом urls(forResourcesWithExtension, гарантированно существует на 100%, а принудительный try! безопасен.Другие дополнительные привязки также не нужны

0 голосов
/ 26 апреля 2018

попробуйте загрузить данные файла

func load(file name:String) -> String? {
        guard let filepath = Bundle.main.path(forResource: name, ofType: "txt") else {
            return nil
        }

        do {
            let contents = try String(contentsOfFile: filepath, encoding: String.Encoding.utf8)
            return contents
        }
        catch {
            print("Read Error")
            return nil
        }
    }

Вы можете использовать

if let data = self.load(file: "YourFileName") {
    print(data)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...