【Swift】URLの画像(Image)をドキュメントフォルダ(アプリ)内に保存する方法!

この記事からわかること

  • SwiftURLから画像取得する方法
  • 取得した画像をアプリ(Documentsディレクトリ)内に保存するには?
  • Google Books APIs表紙ローカルの保存する方法

index

[open]

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

みんなの誕生日

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

posted withアプリーチ

URLの画像(Image)をドキュメントフォルダ(アプリ)内に保存する方法

Swiftを使用してAPIなどから受け取った画像URLから画像(Image)を取得し、アプリのサンドボックス内のDocumentsディレクトリの中に保存する方法をまとめていきます。

おすすめ記事:iOSのファイルシステム:サンドボックス構造とは?

今回は例としてGoogle Books APIsから本の表紙を取得してローカルに保存してアプリを停止させても参照できるようにしていきたいと思います。また保存する画像ファイル名は重複を避けるためにURLを含んだファイル名にしておきます。

流れ

  1. APIから画像URLを取得
  2. URL型へキャスト
  3. Data型へキャスト
  4. UIImage型へキャスト
  5. Data型(jpeg)へキャスト
  6. writeメソッドでdocumentsディレクトリに保存

Data(contentsOf:)でURLからデータを取得してData型に変換しています。そこからUI Imageクラスのwrite(to:)メソッドを使用して画像データをDocumentsディレクトリに保存しています。ファイル名をURLにするためにreplacingOccurrences/!に変換しています。

class ImageFileManager {
    // MARK: - パスの構築

    private func docURL(_ fileName: String) -> URL? {
        do {
            // Docmentsフォルダを取得
            let docsUrl = try FileManager.default.url(
                for: .documentDirectory,
                in: .userDomainMask,
                appropriateFor: nil,
                create: false
            )
            // URLを構築
            let url = docsUrl.appendingPathComponent(fileName)
            return url
        } catch {
            return nil
        }
    }

    public func savingImage(urlStr: String) {
        do {
            // URLの文字列をUIImage型に変換
            guard let url = URL(string: urlStr) else { return }
            let data = try Data(contentsOf: url)
            guard let image = UIImage(data: data) else { return }
            guard let imageData = image.jpegData(compressionQuality: 1.0) else { return }

            let name = urlStr.replacingOccurrences(of: "/", with: "!") // スラッシュではなぜか保存できなかった
            try imageData.write(to: docURL("\(name).jpg")!)
            print("画像を保存できました")
        } catch {
            print("\(error)")
        }
    }
}

保存してある画像を取得する方法

Documentsディレクトリの中に保存している画像データはUIImage(contentsOfFile:)を使用して取得できます。その前にFileManagerクラスのfileExistsメソッドで存在するかどうかを識別しています。

また今回はSwift UIで使用したかったためImage構造体に変換して返しています。

public func loadImage(urlStr: String) -> Image {
    let name = urlStr.replacingOccurrences(of: "/", with: "!")  // スラッシュではなぜか保存できなかった
    let path = docURL("\(name).jpg")!.path
    if FileManager.default.fileExists(atPath: path) {
        if let image = UIImage(contentsOfFile: path) {
            return Image(uiImage: image)
        } else {
            print("読み込みに失敗しました")
        }
    } else {
        print("画像が見つかりませんでした")
    }
    return Image(systemName: "trash")
}

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

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

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

searchbox

スポンサー

ProFile

ame

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

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

New Article

index