Прочитать текстовый файл по строкам в Swift?

Просто начал изучать Swift, у меня есть мой код для чтения из текстового файла, и приложение отображает содержимое всего текстового файла. Как я могу отображать строки за строкой и вызывать эту строку несколько раз?

TextFile.txt содержит следующее.

  • Банан
  • Apple,
  • груша
  • клубника
  • черника
  • черной смородины

в настоящее время существует следующее.

  if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
        var data = String(contentsOfFile:path, encoding: NSUTF8StringEncoding, error: nil)
            if let content = (data){
                TextView.text = content
    }

Также, если есть другой способ, сделайте это, пожалуйста, дайте мне знать. Очень ценится

Ответ 1

Swift 3.0

if let path = Bundle.main.path(forResource: "TextFile", ofType: "txt") {
    do {
        let data = try String(contentsOfFile: path, encoding: .utf8)
        let myStrings = data.components(separatedBy: .newlines)
        TextView.text = myStrings.joined(separator: ", ")
    } catch {
        print(error)
    }
}

Переменная myStrings должна быть каждой строкой данных.

Используемый код: Чтение файла по строкам в SDK iOS, написанное в Obj-C и использующее NSString

Проверьте историю изменений для предыдущих версий Swift.

Ответ 2

Обновление для Swift 2.0/Xcode 7.2

    do {
        if let path = NSBundle.mainBundle().pathForResource("TextFile", ofType: "txt"){
            let data = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)

            let myStrings = data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
            print(myStrings)
        }
    } catch let err as NSError {
        //do sth with Error
        print(err)
    }

Также стоит упомянуть, что этот код читает файл, который находится в папке проекта (поскольку используется pathForResource), а не в. папка документов устройства

Ответ 3

Вероятно, самый простой и легкий способ сделать это в Swift 5.0 будет следующим:

import Foundation

// Determine the file name
let filename = "main.swift"

// Read the contents of the specified file
let contents = try! String(contentsOfFile: filename)

// Split the file into separate lines
let lines = contents.split(separator:"\n")

// Iterate over each line and print the line
for line in lines {
    print("\(line)")
}

Кредит идет на: https://wiki.codermerlin.com/mediawiki/index.php/Code_Snippet:_Print_a_File_Line-by-Line

Ответ 4

Возможно, вы захотите сразу прочитать весь файл. Уверен, что он очень маленький.

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

Простой пример:

    var x: String = "abc\ndef"
    var y = x.componentsSeparatedByString("\n")
    // y is now a [String]: ["abc", "def"]

Ответ 5

Это не красиво, но я считаю, что это работает (на Swift 5). При этом используется основная команда POSIX getline для итерации и чтения файла.

typealias LineState = (
  // pointer to a C string representing a line
  linePtr:UnsafeMutablePointer<CChar>?,
  linecap:Int,
  filePtr:UnsafeMutablePointer<FILE>?
)

/// Returns a sequence which iterates through all lines of the the file at the URL.
///
/// - Parameter url: file URL of a file to read
/// - Returns: a Sequence which lazily iterates through lines of the file
///
/// - warning: the caller of this function **must** iterate through all lines of the file, since aborting iteration midway will leak memory and a file pointer
/// - precondition: the file must be UTF8-encoded (which includes, ASCII-encoded)
func lines(ofFile url:URL) -> UnfoldSequence<String,LineState>
{
  let initialState:LineState = (linePtr:nil, linecap:0, filePtr:fopen(fileURL.path,"r"))
  return sequence(state: initialState, next: { (state) -> String? in
    if getline(&state.linePtr, &state.linecap, state.filePtr) > 0,
      let theLine = state.linePtr  {
      return String.init(cString:theLine)
    }
    else {
      if let actualLine = state.linePtr  { free(actualLine) }
      fclose(state.filePtr)
      return nil
    }
  })
}

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

for line in lines(ofFile:myFileURL) {
  print(line)
}