2017-01-13 6 views
0

テキストファイルを1行ずつ読み込み、example shown hereを使用してiOS画面に表示したいとします。なぜBundle.main.path(forResource:fileName、ofType: "txt")は常にnilを返しますか?

textView.textをオプションにすることは、readDataFromFileを実行する唯一の方法でした。 loadをクリックすると、関数は実行されますが、常にnilが返されます。私はこれがファイルが見つからないことを意味すると仮定します。

テストの目的で、私はXcodeでテキストファイルを作成しました。私はまた、デスクトップとプロジェクトフォルダに保存しようとしました。いずれにしても、プロジェクトナビゲータから読み込み可能でした。また、アプリケーションが最終的にXcode以外で作成されたテキストファイルを読み込む必要があるため、TextEditを使用してファイルを作成しようとしました。

テキストファイルが見つからない理由がわかっている場合、またはプロジェクトがそれを見つけるために何か必要があるかどうか、あるいは読んだ関数が何らかの理由でnilを返すかどうかを説明できるのであれば、私がそれを実装した方法に。ありがとう。フィードバックのため

EDIT(2)

おかげ。これに対応して、テキストファイルの内容をtextViewに書き込むための4つのマイナーコードの変更を行いました。変更には、ファイル名からファイル拡張子を削除し、ファイル名の配列を追加し、String?の代わりにStringを返し、readDataFromFileからUITextViewをコードに書き換えます。これは私が認識している問題を解決しました。

はここで改訂されたコード

import UIKit 

class ViewController: UIViewController { 

var textView = UITextView() 
var arrayOfStrings: [String]? 
var fileNameWithExtension    = "textFile.txt" 
let arrayOfFileNames     = ["textFile1.txt", "textFile2.txt", "textFile3.txt", "textFile4.txt", "textFile5.txt"] 

var fileName       = String() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // remove comment in the next statement to test files named in ArrayOfFileNames  
    // fileNameWithExtension    = arrayOfFileNames[4] 

    fileName = fileNameWithExtension.replacingOccurrences(of: ".txt", with: "") 

    createTextView() 
    createButton() 
} 

func readDataFromFile(fileName: String) -> String { 

    if let path       = Bundle.main.path(forResource: fileName, ofType: nil) { 

     print(fileName) 

     do { 
      let data     = try String(contentsOfFile: path, encoding: String.Encoding.utf8) 
      arrayOfStrings    = data.components(separatedBy: .newlines) 
      textView.text    = arrayOfStrings?.joined(separator: "\n") 

     } catch { 
      textView.text    = "file contents could not be loaded" 
     } 

    } else { 
     print(Bundle.main.path(forResource: fileName, ofType: "txt") as Any) 
     textView.text     = "\(fileName) could not be found" 
    } 
    return textView.text 
} 

func createButton() { 
    let button = UIButton(); 
    button.setTitle(String("Load"), for: .normal) 
    button.setTitleColor(UIColor.blue, for: .normal) 
    button.frame = CGRect(x: 100, y: 10, width: 200, height: 100) 
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) 
    self.view.addSubview(button) 
} 

func buttonAction(myButton: UIButton) { 
    textView.text = readDataFromFile(fileName: fileName) 
    print(textView.text as Any) 
} 

func createTextView() { 
    textView = UITextView(frame: CGRect(x: 20.0, y: 75.0, width: 340.0, height: 400.0)) 
    textView.textAlignment = NSTextAlignment.left 
    textView.textColor = UIColor.blue 
    textView.backgroundColor = UIColor.white 
    self.view.addSubview(textView) 
    } 
} 

EDIT(1)

ファイルは、プロジェクトナビゲータに表示されます。私はそれが束に入っていることを意味します。ここで

が私の元のコードはtextFile.txt

import UIKit 

class ViewController: UIViewController { 

@IBOutlet weak var textView: UITextView? 

var arrayOfStrings: [String]? 
var fileName       = "textFile.txt" 

override func viewDidLoad() { 
    super.viewDidLoad() 
    createButton() 
} 

func readDataFromFile(fileName: String) -> String? { 

    if let path       = Bundle.main.path(forResource: fileName, ofType: "txt") { 
     print(fileName) 

     do { 
      let data     = try String(contentsOfFile: path, encoding: String.Encoding.utf8) 
      arrayOfStrings    = data.components(separatedBy: .newlines) 
      print(arrayOfStrings as Any) 

      textView?.text    = arrayOfStrings?.joined(separator: "/n") 
      return textView?.text 

     } catch { 
      textView?.text    = "file contents could not be loaded" 
      return textView?.text 
     } 

    } else { 
     print(Bundle.main.path(forResource: fileName, ofType: "txt") as Any) 
     textView?.text     = "\(fileName) could not be found" 
     return nil 
    } 
} 

func createButton() { 
    let button = UIButton(); 
    button.setTitle(String("Load"), for: .normal) 
    button.setTitleColor(UIColor.blue, for: .normal) 
    button.frame = CGRect(x: 100, y: 15, width: 200, height: 100) 
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) 
    self.view.addSubview(button) 
} 


func buttonAction(myButton: UIButton) { 
    print("works") 
    textView?.text      = readDataFromFile(fileName: fileName) 
    print(textView?.text as Any) 
} 

ある

Line 1 
Line 2 
Line 3 
Line 4 
Line 5 
+2

'fileName'は' textFile'(拡張子なし) – vadian

+0

...または 'fileName'にすでに拡張子" .txt "が含まれている場合は' Bundle.main.path(forResource:fileName、ofType:nil) 'を呼び出します。 " –

+1

...またはURL関連APIの「バンドル」を使用してください。main.url(forResource: "textFile"、withExtension: "txt") 'これはより説明的です。 – vadian

答えて

7

1)あなたは、この行に誤りがあります。

var fileName = "textFile.txt" 

は次のようになります。

var fileName = "textFile" 

2)チェックがターゲットに接続されているファイルです:

enter image description here

+0

は違いがありません – Greg

+1

チェック、あなたは "textFile.txt"の正しいターゲットを設定しました – Igor

+0

私はあなたが意味すると思います: "textFile.txt"がバンドルにあります。私の編集を参照 – Greg

1

あなたは、このようなクラスのバンドルの所有者を追加することを検討すべきである:

Bundle(for: ViewController.self).path(forResource: "fileName", ofType: "txt") 

私がいた場合、これは、迅速2.0から実装されました右。

+1

あなたはこれのためにメダルに値する!私は、複数のxcodeプロジェクトのセットアップがあります。私の 'MainApp.xcodeproj'では' MyModule.xcodeproj'を参照し、 'MyModule'の中で私は' MyModule'のターゲットの一部であったアセット、ビデオファイル(mp4)を参照しました。しかし、 'MyModule'のファイルの中で' Bundle.main'というコードを使うのは 'MyModule'ではなく' MainApp'です。したがって、あなたのソリューションを 'Bundle(for:FileInsideMyModulesTarget.self).path'で使用すると、私の問題は解決しました! :D – Sajjon

関連する問題