質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.83%

  • Swift

    6514questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Xcode

    3767questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

TableViewのデータをファイルに保存したい

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 171

textfieldに入力した値をテーブルに反映しています。
そこで、テーブルに表示されているデータを.csv/.txtでDocuments下に保存したいのですが、どうもうまくいきません。
現段階ではDocuments下に.csv/.txtでファイルを作成まではできたのですが、なぜか中身が
空になっています。よろしければご教授ください。

import UIKit
import RealmSwift

class ViewController: UIViewController, UIPickerViewDelegate, UITextFieldDelegate,UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIPickerViewDataSource {

    var laps: [String] = []

    var timer = Timer()
    var minutes: Int = 0
    var seconds: Int = 0
    var fractions: Int = 0


    var stopwacthString: String = ""

    var startStopWacth: Bool = true
    var addLap: Bool = false


    @IBOutlet weak var name: UITextField!
    @IBOutlet weak var stopwacthLabel: UILabel!
    @IBOutlet weak var todoNameText: UITextField!

    let pickerOptions = [["","白","青","-","第1ピリオド","第2ピリオド","第3ピリオド","第4ピリオド"],["","1", "2", "3","4", "5", "6","7", "8", "9","10", "11", "12","13", "14", "15","16", "17", "18","19", "20"],["","AG", "P", "E","ES", "B", "BP","TO", "PG", "EG"],["","0-","1-", "2-", "3-","4-", "5-", "6-","7-", "8-", "9-","10-", "11-", "12-","13-", "14-", "15-","16-", "17-", "18-","19-", "20-"],["","0","1", "2", "3","4", "5", "6","7", "8", "9","10", "11", "12","13", "14", "15","16", "17", "18","19", "20"]]

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var startstopButton: UIButton!
    @IBOutlet weak var lapresetButton: UIButton!
    @IBOutlet weak var resetButttom: UIButton!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        name.placeholder = "ファイル名(試合名など)を入力"

        let pickerview = UIPickerView()
        pickerview.delegate = self
        todoNameText.inputView = pickerview

           }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        stopwacthLabel.text = "00:00.00"
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {

        return pickerOptions.count

    }
    func  pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        return pickerOptions[component].count

    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        return pickerOptions[component][row]

    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        let model = pickerOptions[0][pickerView.selectedRow(inComponent: 0)]
        let color = pickerOptions[1][pickerView.selectedRow(inComponent: 1)]
        let AC = pickerOptions[2][pickerView.selectedRow(inComponent: 2)]
        let White = pickerOptions[3][pickerView.selectedRow(inComponent: 3)]
        let Blue = pickerOptions[4][pickerView.selectedRow(inComponent: 4)]

        todoNameText.text =  "    " + stopwacthString + "            " + model + "            " + color + "          " + AC + "      " + White + "" + Blue

    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        view.endEditing(true)

    }
    func updateStopwacth() {

        fractions += 1
        if fractions == 100 {

            seconds += 1
            fractions = 0
        }
        if seconds == 100 {

            minutes += 1
            seconds = 0
        }

        let franctionsString = fractions > 9 ?"\(fractions)" : "0\(fractions)"
        let secondsString = seconds > 9 ?"\(seconds)" : "0\(seconds)"
        let minutesString = minutes > 9 ?"\(minutes)" : "0\(minutes)"

        stopwacthString = "\(minutesString):\(secondsString)"
        stopwacthLabel.text = stopwacthString
    }

    @IBAction func SaveButtom(_ sender: Any) {

        let name = self.name.text ?? "unknown"
        let thePath = NSHomeDirectory()+"/Documents/\(name).csv"

        let textData = todoNameText?.text

        do {

            try textData?.write(toFile: thePath, atomically: true, encoding: String.Encoding.utf8)
        } catch let error as NSError {
            print("保存に失敗。\n \(error)")
        }
        // ① UIAlertControllerクラスのインスタンスを生成
        // タイトル, メッセージ, Alertのスタイルを指定する
        // 第3引数のpreferredStyleでアラートの表示スタイルを指定する
        let alert: UIAlertController = UIAlertController(title: "作成スコアを保存", message: "保存したデータは”データを送信する”からPCへ送信できます。", preferredStyle:  UIAlertControllerStyle.alert)

        // ② Actionの設定
        // Action初期化時にタイトル, スタイル, 押された時に実行されるハンドラを指定する
        // 第3引数のUIAlertActionStyleでボタンのスタイルを指定する
        // OKボタン
        let defaultAction: UIAlertAction = UIAlertAction(title: "保存", style: UIAlertActionStyle.default, handler:{
            // ボタンが押された時の処理を書く(クロージャ実装)
            (action: UIAlertAction!) -> Void in
            print("保存")
        })
        // キャンセルボタン
        let cancelAction: UIAlertAction = UIAlertAction(title: "保存しない", style: UIAlertActionStyle.cancel, handler:{
            // ボタンが押された時の処理を書く(クロージャ実装)
            (action: UIAlertAction!) -> Void in
            print("保存しない")
        })

        // ③ UIAlertControllerにActionを追加
        alert.addAction(cancelAction)
        alert.addAction(defaultAction)

        // ④ Alertを表示
        present(alert, animated: true, completion: nil)

           }
    @IBAction func addToDo(_ sender: Any) {


        if isValidateInputContents() == false{
            return
        }



    // ToDoデータを作成する処理
    let toDo = ToDo()
    toDo.name = todoNameText.text!

    // ToDoデータを永続化する処理
    do{
    let realm = try Realm()
    try realm.write{
    realm.add(toDo)
    }
    todoNameText.text = ""
    }catch{
    print("失敗")
    }
    tableView.reloadData()
}


private func isValidateInputContents() -> Bool{
    // ToDo名のデータ入力
    if let name = todoNameText.text{
        if name.characters.count == 0{
            return false
        }
    }else{
        return false
    }
    return true
}

}




extension ViewController: UITableViewDataSource{



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return toDoItems?.count ?? 0

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let toDo = toDoItems?[indexPath.row]



        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! ToDoTableViewCell
        // Realmに登録したデータをラベルに値設定


        cell.nameLabel.text = toDo?.name

        print(toDo?.name)


        return cell

    }



// 削除処理
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == UITableViewCellEditingStyle.delete {

            let realm = try!Realm()

            _ = try!Realm().objects(ToDo.self)

            // これはRealmSwiftでデータを削除しているケース
            let deleteHistory = self.toDoItems?[indexPath.row]
            // トランザクションを開始してオブジェクトを削除します
            try! realm.write {
                realm.delete(deleteHistory!)
            }


            // TableViewを再読み込み.
            self.tableView.reloadData()


        }

    }



}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

addToDo がどのタイミングで呼ばれるか分かりませんが、
そこで「todoNameText.text = ""」としているようですので、
SaveButtomのタイミングでは空文字列であったりしませんか。

ステップ実行でファイルに書き込む際のtextDataの中身を確認してはいかがでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/23 18:06

    todoNameText は textfield で ここに入れたデータを addToDo でtableView に挿入しています。
    todoNameText はaddToDo でデータを挿入したら todoNameText で空白になります。
    なので let textData = todoNameText.text でファイルは空のままなのでしょうか?
    そうすると、let textData = に何を入れれば tableView のデータがファイルに書き込めるのでしょうか?

    説明不足かもしれませんが、宜しくお願いします!

    キャンセル

  • 2017/12/23 20:22

    tableViewは表示するものであって、何かに使うデータを保持するものではありません。
    テーブルで表示している内容をファイルに保存する場合はcellForRowAt でtableViewのCellに入れているデータを使うべきです。
    toDoItemsから書き込むデータを取得してはいかがでしょうか。

    キャンセル

  • 2017/12/24 01:00

    toDoItemsでデータ取得できました!ありがとうございます!!
    ただ表示がこのようになってしまうのですが、これは仕方ないのでしょうか?
    name の値だけ取り出すことは可能ですか?
    何度もすみません
    " [0] ToDo {"
    " name = 00:02 白 2 AG 0-0;"
    " deadLine = 1970-01-01 00:00:00 +0000;"
    " isComplete = 0;"
    " }"
    " [1] ToDo {"
    " name = 00:02 白 3 AG 0-4;"
    " deadLine = 1970-01-01 00:00:00 +0000;"
    " isComplete = 0;"
    " }"
    )

    キャンセル

  • 2017/12/24 02:33

    ToDoというクラスの配列になっているようですので、toDoItems[0].name というように取得すれば良いのではないでしょうか。

    キャンセル

  • 2017/12/24 08:06

    let textData = toDoItems?[0].name.description
    これで0行目のデータは取得できました。[ ]内の値をどのように変えれば全行目の値を一気に取得できますか?

    キャンセル

  • 2017/12/24 13:41

    forEach などで配列をループ処理してください。

    キャンセル

  • 2017/12/25 01:37

    ありがとうございます!forEach関数、調べてやってみます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    6514questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Xcode

    3767questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。