読者です 読者をやめる 読者になる 読者になる

Swift,Objective-Cプログラミング ~ iOS ~

Objective-C,Swift,Apple Watchなどのプログラミング

【iOS Swift入門 #294】Zipファイルの圧縮・解凍チュートリアル(Tutorial)

はじめに

iOS Swiftを使ったZipファイルの圧縮・解凍のTutorial(チュートリアル)です。

この記事を読んでわかること

  • SwiftでZipファイルを圧縮・解凍する方法
  • ライブラリSSZipArchiveの使い方

Zipファイルの圧縮・解凍に使うライブラリ

SSZipArchiveというライブラリを使います。
Github上でStarやForkの数が多く、更新頻度も多いので安心です。

以下ではSwiftでコードを書いていますが、
このLibraryはObjective-Cでも利用できます。

プロジェクトへの追加方法

具体的な追加方法は公式ページを参照してください。

  • CocoaPods
  • Carthage
  • ソースをプロジェクトに追加

で追加することができます。

解凍

SSZipArchiveクラスのunzipFile:atPath:toDestinationメソッドを使う。
解凍するためのメソッドは他にも用意されていますが、
詳細は公式ページやソースを確認してください。

引数に解凍するZipファイルのパスと、解凍先フォルダのパスを渡します。

// path for zip file
let atZipFilePath = fileURLInBundle(name: "sample", ofType: "zip")!.path

// destination path to unzip
let unZipFilePath = documentDirectory.path

// exec unzip
SSZipArchive.unzipFile(atPath: atZipFilePath, toDestination: unZipFilePath)

圧縮

SSZipArchiveクラスのcreateZipFile:atPath:withFilesAtPathsメソッドを使う。
圧縮するためのメソッドは他にも用意されていますが、
詳細は公式ページやソースを確認してください。

引数に圧縮したZipファイルの格納先パスと、圧縮対象のファイルパス(配列)を渡します。

// zip file path
let atZipFilePath = documentDirectory.appendingPathComponent("files.zip").path

// files containing into zip file
let targetFile = fileURLInBundle(name: "sample_text", ofType: "txt")!.path
let targetFile2 = fileURLInBundle(name: "sample_text2", ofType: "txt")!.path

// exec zip
SSZipArchive.createZipFile(atPath: atZipFilePath, withFilesAtPaths: [targetFile, targetFile2])

サンプル

↓からサンプルプロジェクトをダウンロードし確認してみてください。
SampleZipArchiveTutorial.zip - Google ドライブ

ボタンを押したときにコンソールに圧縮先、解凍先のパスを出力しています。
シミュレーターでボタンを押し、出力されたパスをMacで開き、結果を確認しましょう。

  • 圧縮 * f:id:fjswkun:20161210180341p:plain

f:id:fjswkun:20161210180354p:plain

  • 解凍 * f:id:fjswkun:20161210180439p:plain

f:id:fjswkun:20161210180447p:plain

import UIKit
import SSZipArchive

class ViewController: UIViewController {
    @IBOutlet weak var zippedFilePathLabel: UILabel!
    @IBOutlet weak var unzippedFilePathLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func tapZipbutton(_ sender: UIButton) {
        clearDocumentDirectory()
        
        // zip file path
        let atZipFilePath = documentDirectory.appendingPathComponent("files.zip").path

        // files containing into zip file
        let targetFile = fileURLInBundle(name: "sample_text", ofType: "txt")!.path
        let targetFile2 = fileURLInBundle(name: "sample_text2", ofType: "txt")!.path

        // exec zip
        SSZipArchive.createZipFile(atPath: atZipFilePath, withFilesAtPaths: [targetFile, targetFile2])
        
        // show result
        zippedFilePathLabel.text
            = FileManager.default.fileExists(atPath: atZipFilePath)
            ? "created zipfile"
            : "creating zipfile failed"
        
        print(atZipFilePath)
    }
    
    @IBAction func tapUnzipButton(_ sender: UIButton) {
        clearDocumentDirectory()
        
        // path for zip file
        let atZipFilePath = fileURLInBundle(name: "sample", ofType: "zip")!.path

        // destination path to unzip
        let unZipFilePath = documentDirectory.path

        // exec unzip
        SSZipArchive.unzipFile(atPath: atZipFilePath, toDestination: unZipFilePath)
        
        
        // show result
        unzippedFilePathLabel.text
            = FileManager.default.fileExists(atPath: unZipFilePath)
            ? "unzipped"
            : "failed unzip"
        
        print(unZipFilePath)
    }
    
    // file url in main bundle
    private func fileURLInBundle(name:String?, ofType:String?) -> URL?{
        guard let path = Bundle.main.path(forResource: name, ofType: ofType) else{
            return nil
        }
        return URL(fileURLWithPath: path)
    }
    
    // documentFirectory's url
    private let documentDirectory:URL = {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    }()
    
    // clear all files in documentDirectory
    private func clearDocumentDirectory(){
        do{
            let fileURLs = try FileManager.default.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles, .skipsPackageDescendants, .skipsSubdirectoryDescendants])
            
            for url in fileURLs{
                try FileManager.default.removeItem(at: url)
            }
        }catch(let ex){
            print(ex.localizedDescription)
        }
    }
}

参考情報

Zip

Swift

入門書籍

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第5版
プログラミングが初めて!という人が小さなアプリを作ることで、アプリ開発を学ぶことができます。
「Swiftだけでなく、プログラミング自体が初めてなんだけど、どの本が良い?」と聞かれたときには、
この書籍をおすすめしています。

本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ)
アプリ開発からApp Storeへの公開までの一通りを学ぶことができます。
入門書を2冊、3冊を読んだあとでこの書籍を読むとかなりの実力アップを感じることができます。

ただし、一通り学ぶことができますが、プログラミング初めてでこの書籍を選ぶことはオススメできません。
最初の方の内容はプログラミング初心者には理解が難しく、そこで勉強をやめてしまう可能性がありそうだと感じます。

Swiftポケットリファレンス
辞書として1冊は持ってても良い。

仕事でやれるレベルになるために

初心者から仕事でやれるレベルになるためにオススメできる日本語書籍がみつかりませんでした。
英語は苦手でも、書籍に書かれているソースはやさしく、読み進めることができます。

The iOS Apprentice (英語サイト・英語書籍)
Swift Apprentice (英語サイト・英語書籍)

平均的プログラマーを超えるために

詳解Swift 第3版
Swift3の書籍。第1版、第2版にもお世話になっています。
Swiftの文法についてとても詳しく書いてあります。

Ray Wenderlich | Tutorials for iPhone / iOS Developers and Gamers
QiitaのSwiftに関する記事