【Swift】アプリからCSVファイルを作成・保存・書き込みする方法!

【Swift】アプリからCSVファイルを作成・保存・書き込みする方法!

この記事からわかること

  • SwiftCSVファイル作成する方法
  • 保存追記などの操作
  • デバイス内ないから確認するには?
  • BOM付きUTF-8とは?
  • OutputStream使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

CSVファイルとは?

そもそもCSVファイルとは「Comma-Separated Values」の略称で直訳すると「カンマで区切られた値」という意味になります。

ファイル名通りCSVファイルは行単位にカンマ(,)区切りで値が区切られているテキストファイル形式です。

Excelを使用してCSVファイルを開くことができますが、「0落ち(001が1になる)」や「文字化け」、「日付変換」などそれなりに問題は多いです。

CSVファイル自体はフォーマットに準じた普通のテキストファイルなのでSwiftでも簡単に作成することができます。

SwiftでCSVファイルを構築する方法

Swiftで CSVファイルを構築するにはCSVの記述形式に倣ったデータをファイルに書き込むだけです。まずはCSV形式の文字列を定義します。

以下のようにカンマを使って値を区切り、行の終わりには改行コード(\r\n)を渡します

let csv = "name,age,like\r\name,26,chocolat\r\nkasa,20,hamburger\r\n"

CSVファイルをデバイスに保存する

「デバイスに保存」と書きましたが厳密には「アプリ内のフォルダへのアクセスを許可する」になります。

作成したCSVファイルはアプリのDocumentsフォルダへ保存します。そしてそのDocumentsフォルダを「ファイル」アプリからアクセス可能にすることで表示できるようにします。そのためには設定が必要なので以下記事を参考に設定しておいてください。

おすすめ記事:【Swift】ファイルアプリからDocumentsフォルダへアクセス許可する方法!

では実際にUIKitベースでコードにしていきます。コピペだけで動作するように作っていくので試してみてください。まずはUIを配置します。

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton()
        button.frame = CGRect(x: 0, y:0, width: 100 , height: 100)
        button.backgroundColor = .orange
        button.center = self.view.center
        button.addTarget(self, action: #selector(createFile), for: .touchUpInside)
        self.view.addSubview(button)
    }
  }

続いてボタン押下時にCSVファイルをDocumentsフォルダに生成する処理を記述します。ファイル操作にはFileManagerクラスを使用します。

おすすめ記事:【Swift】FileManagerでファイルを保存!操作方法や格納場所

@objc  func createFile() {
    // Documentsディレクトリまでのパスを生成
    let fileManager = FileManager.default
    let docPath =  NSHomeDirectory() + "/Documents"
    let filePath = docPath + "/sample.csv"
        
    let csv = "name,age,like\r\name,26,chocolat\r\nkasa,20,hamburger\r\n"
    let data = csv.data(using: .utf8)
    
    if !fileManager.fileExists(atPath: filePath) {
        fileManager.createFile(atPath:filePath, contents: data, attributes: [:])
    }else{
        print("既に存在します。")
    }
}

FileManagerクラスを使用して保存先のパスとファイル名を指定し、CSVデータは文字列で定義後Data型に変換しFileManagerクラスに渡します。

これでボタンを押すとCSVファイルが生成されているので確認してみます。シミュレーター内の「ファイル」アプリから、「このiPhone内」>「アプリ名」>「ファイル名」を確認し以下のように生成したファイルを確認できれば成功です。

【Swift】ファイルアプリからDocumentsフォルダへアクセス許可する方法!

開いてみるとExcelのように値がセルごとに区切られた形式で正しく保存されていることを確認できます。

【Swift】アプリからCSVファイルを作成・保存・書き込みする方法!

またこのファイルをExcelで開いても正常に表示されました。

BOM付きUTF-8にして文字化けを防ぐ

英語や数字のみの場合はExcelでも問題なく表示できましたが、日本語などのマルチバイト文字を含む以下のようなCSVデータの場合は「ファイル」からは正常に表示できましたが、「Excel」からでは文字化けを起こしてしまいました。

let csv = "名前,年齢,好きなもの\r\nあめ,26,チョコレート\r\nかさ,20,ハンバーガー\r\n"
【Swift】アプリからCSVファイルを作成・保存・書き込みする方法!

これを解決するにはBOM付きUTF-8形式のCSVファイルにする必要があります。

BOM付きUTF-8とは?

UTF-8は文字コード(コンピューター上で文字を表示するための形式)の1つであり、Unicode用の符号化方式です。

BOM(ボム)とは「byte order mark」の略称でファイル先頭に付与される3バイトの識別子です。識別するのは「符号化方式(これはUnicodeのUTF-8だよ)」です。

SwiftでBOMを付与する

公式リファレンス:OutputStream

BOMを付与するにはOutputStreamクラスを使用します。UnicodeのUTF-8のBOMは「U+FEFF」らしいのでそれを付与します。

参考文献:BOM(Byte Order Mark)

ではどうやって付与するのかというとエスケープ文字を使ってUnicodeの文字列が表現できるようなので以下記事を参考に構築していきます。

参考文献:2.3.8. Unicode | 文字列と文字 | Swift

\u{n}形式(n部分に16進数)でUnicodeスカラーが表現できるので\u{feff}とすることでBOMを定義できます。あとはOutputStreamクラスを用いてCSVファイルを作成するコードに書き換えます。

@objc  func createFile() {
    
    let fileManager = FileManager.default
    guard let docURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else{
        fatalError("URL取得失敗")
    }
    let filePath = docURL.appendingPathComponent("sample.csv")
    
    if let strm = OutputStream(url:filePath, append: false) {
        strm.open()
        defer {
            strm.close()
        }
        
        let BOM = "\u{feff}"
        
        strm.write(BOM, maxLength: 3)
        
        let csv = "名前,年齢,好きなもの\r\nあめ,26,チョコレート\r\nかさ,20,ハンバーガー\r\n"
        let data = csv.data(using: .utf8)
        
        let _ = data?.withUnsafeBytes {
            strm.write($0, maxLength: Int(data?.count ?? 0))
        }
    }else{
        print("false")
    }
}

コードはガッツリ変更になりましたが正常にファイルアプリからCSVファイルが表示でき、またExcelからも以下のように文字化けを起こすことなく表示できるようになりました。

【Swift】アプリからCSVファイルを作成・保存・書き込みする方法!

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index