プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

ブログを始めて1ヶ月が過ぎました。

始めたきっかけ

始めた当初は続けられるか心配しましたが、何とか続いています。
始めたきっかけは、

  • アフェリエイトに興味がわいた。
  • 自分が修得した技術情報を、文章にまとめて、外部に発信したくなった。
  • 書く技術を向上させたくなった。

の3つの理由でした。

今のところはてなブログの使い方、Markdownの書き方、アフェリエイトの仕組みを勉強しながらブログを書いています。
まだ書く技術については勉強できていないです。

日々の生活や仕事に追われ時間があまりないですが、ちょっとずつ楽しみながら続けています。
前に記事にも書きましたが、新しいことを覚えたり、始めたりするのが、一番楽しいです。

実践C++/CLI 極めるための基礎と実用テクニック

実践C++/CLI 極めるための基礎と実用テクニック

目標

当面の目標は次の2つです。

  • 毎日更新する。
  • 3か月は続ける。

今はネタのストックはあるので、記事を書く時間さえあれば目標はクリアできそうです。
ただ3か月以降続ける場合、そのうちソフトウェア技術系のネタだけでは持ちそうにないかなぁって感じています。

ソフトウェア技術系以外のネタも、と考えましたがあんまりかけ離れたネタだと、何のブログがわからなくなりそうなので、悩みどころです。

最近、1つアイデアが浮かんだのですが、問題はちょっと時間がかかるので、どうやって進めるか、これも悩みどころです。

どんな情報?

ちなみにソフトウェア技術系のネタは次の5つを考えています。

ただし下の3つは情報が古いです。
Android、サーバサイドJavaは、かつて長い間業務で使っていましたが、その業務から離れてもう何年もたってしまいました。
Cに至っては、学生~入社当初使っていましたが、入社してすぐサーバサイドJavaの業務担当になったので、一般的な情報しか知りません。

となると現在業務で使っているC++/CLI、または個人的にiOSアプリ開発で使っているSwiftが、メインになりそうです。

お願い

一言でもいいのでコメントいただけたら嬉しいです。
またこんなことを調べて記事にしてほしいなど、要望でも構いません。

自作アプリを作った時に思ったのですが、AppleStoreのレビューや、アプリ内の不具合/要望報告メール、お問い合わせサイトから、ユーザの声があるとものすごくモチベーションが上がりました。
このブログでも、そんな声をいただけるようにがんばりたいと思っています。

今後ともよろしくお願いします。

Tech Boost

詳解 Swift 第4版

詳解 Swift 第4版

PWEditor:SwiftのDropbox APIでファイル名をリネームする。

目次

  1. はじめに
  2. リネーム処理
  3. おわりに

1. はじめに

今回はリネーム処理の説明です。
Dropbox APIでリネームを行うメソッドは見つけられませんでした。
そのためPWEditorでは、移動で使用したmoveV2メソッドを使ってリネーム処理を実装しました。

目次へ

2. リネーム処理

リネームの方法ですが、リネームしたいディレクトリやファイルのパス部分は変更せず、ディレクトリ名やファイル名を 変のみ更して、移動させることで実現しています。
例えば、"/dir1/dir2”にある"file1.txt"というファイル名を"file2.txt"に変更する場合、

  • 変更前ファイル名 : "/dir1/dir2/file1.txt"
  • 変更後ファイル名 : "/dir1/dir2/file2.txt"

として、moveV2メソッドのfromPath、toPathに指定して処理します。

import SwiftyDropbox

/**
 ディレクトリやファイル名をリネームします。
 
 - Parameter fromPath: 変更前のディレクトリまたはファイルのパス名
 - Parameter toPath: 変更後のディレクトリまたはファイルのパス名
 */
func rename(fromPath: String, toPath: String) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    let _ = client.files.moveV2(fromPath: fromPathName, toPath: toPath).response { response, error in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        guard let response = response else {
            // レスポンスがない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // 正常終了の場合の処理を記述してください。
    }
}

API Reference
moveV2メソッド

目次へ

3. おわりに

今回でPWEditorで使用しているDropbox APIの説明は全て説明しました。
PWEditorではこれらの機能の他に、他のストレージへのインポート、エクスポート機能もありますが、今まで説明した機能で実現しています。

【IT派遣テクノウェイブ】

目次へ

PWEditor:SwiftのDropbox APIでファイル削除する。

目次

  1. はじめに
  2. ファイル削除処理
  3. おわりに

Swift 4プログラミング入門 iOS 11+Xcode 9対応

Swift 4プログラミング入門 iOS 11+Xcode 9対応

1. はじめに

Dropboxでファイルを削除する機能の説明です。

目次へ

2. ファイル削除処理

Dropboxの削除はdeleteV2メソッドで行います。
引数は、削除するファイル名またはディレクトリのパス名になります。
ディレクトリの場合、配下のディレクトリやファイルごと削除されます。

PWEditorでは、削除前に確認ダイアログを表示して、削除確認を行ってから削除しています。

/**
 ファイルやディレクトリを削除します。
 
 - Parameter pathName: 削除するファイルまたはディレクトリのパス名
 */
func deleteFile(pathName: String) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    // ファイルまたはディレクトリを削除します。
    let _ = client.files.deleteV2(path: pathName).response { (result: Files.DeleteResult?, error: CallError<Files.DeleteError>?) in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        // 正常終了の場合の処理を記述してください。
    }
}

API Reference
deleteV2メソッド

目次へ

3. おわりに

PWEditorは、iCloudGoogle Drive、One Driveの他のストレージも同じ機能を提供するため、それぞれのAPIを使用しています。
そのなかでDropboxAPIがいちばん統一感があって、使いやすいです(たまに直感的ではないメソッド名もありますが)
先に説明したコピー、移動、削除のAPIは、ほとんど同じような命名で、同じような使い方なので、すぐに実装できました。

とりあえず稼ぎたいなら、ITエンジニア【IT派遣テクノウェイブ】

目次へ

PWEditor:SwiftのDropbox APIでファイルを移動する。

目次

  1. はじめに
  2. ファイル移動処理
  3. おわりに

1. はじめに

Dropboxの移動機能の説明です。
Dropboxの移動もコピーと同様、ファイルもディレクトリも同じ機能で行えます。

目次へ

2. ファイル移動処理

Dropboxの移動はmoveV2メソッドで行います。
引数はシンプルに、移動元のパス名と移動先のパス名になります。
移動元のパス名がディレクトリの場合、ディレクトリが移動されます。
ディレクトリの場合、配下のディレクトリやファイルごと移動されます。
移動先に移動元と同名のファイルやディレクトリが存在する場合、エラーになります。
ほぼコピーと同じような動作になります。

/**
 ファイルやディレクトリを移動します。
 
 - Parameter fromPath: 移動元パス名
 - Parameter toPath: 移動先パス名
 */
func move(_ fromPath: String, toPath: String) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    // ファイルまたはディレクトリを移動します。
    let _ = client.files.moveV2(fromPath: fromPath, toPath: toPath).response { response, error in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        guard let response = response else {
            // レスポンスがない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // 正常終了の場合の処理を記述してください。
    }
}

API Reference
moveV2メソッド

目次へ

3. おわりに

コピーとほとんど同じようなAPIなので、すぐ実装できました。

ドコモ口座キャッシュゲットモール

目次へ

PWEditor:SwiftのDropbox APIでファイルをコピーする。

目次

  1. はじめに
  2. ファイルコピー処理
  3. おわりに

1. はじめに

Dropboxコピー機能の説明です。
Dropboxのコピーは、ファイルもディレクトリも同じ機能で行えます。

目次へ

2. ファイルコピー処理

DropboxのコピーはcopyV2メソッドで行います。
引数はシンプルに、コピー元のパス名とコピー先のパス名になります。
コピー元のパス名がディレクトリの場合、ディレクトリがコピーされます。
ディレクトリの場合、配下のディレクトリやファイルごとコピーされます。
コピー先にコピー元と同名のファイルやディレクトリが存在する場合、エラーになります。

/**
 ファイルやディレクトリをコピーします。
 
 - Parameter fromPath: コピー元パス名
 - Parameter toPath: コピー先パス名
 */
func copy(_ fromPath: String, toPath: String) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    // ファイルまたはディレクトリをコピーします。
    let _ = client.files.copyV2(fromPath: fromPath, toPath: toPath).response { response, error in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        guard let response = response else {
            // レスポンスがない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // 正常終了の場合の処理を記述してください。
    }
}

API Reference
copyV2メソッド

目次へ

3. おわりに

PWEditorはエディタアプリですが、実装していくうちにコピーなどのファイル操作もできると便利だと思いました。
そのためコピー機能を実装しましたが、このころからだんだんエディターアプリの範疇を超えてきた気がします。

TECH::EXPERT

現場のためのSwift4 Swift4.1+Xcode9.3対応

現場のためのSwift4 Swift4.1+Xcode9.3対応

目次へ

PWEditor:SwiftのDropbox APIでファイルを更新する。

目次

  1. はじめに
  2. ファイル更新処理
  3. おわりに

1. はじめに

PWEditorではDropboxのファイルの編集内容は、メモリ上で更新されています。
そのままでは編集した内容は保存されないので、編集した内容をDropbox上のファイルに反映する必要があります。
今回はその手順の説明になります。

目次へ

2. ファイル更新処理

Dropbox上のファイルの更新は、"ファイルを作成する"で使用したuploadメソッドを使います。
ファイルを作成した時とは異なりuploadメソッドの引数は、ファイルパス名、ファイルデータの他にいくつか必要になります。

modeは競合が発生した場合、どのような方針でファイルを更新するか指定します。
PWEditorでは".override"常に上書き保存となっています。

mode 説明
.add 常に新しいファイル名で保存されます。
既存のファイルが存在する場合、例えば元のファイル名が"document.txt"の場合、新しく"document (2).txt"で保存されます。
.overwrite 常に上書き保存されます。
.update 競合していない場合は上書き保存します。
競合した場合は、例えば元のファイル名が"document.txt"の場合、新しく"document (confilicted copy).txt"で保存されます。

autorenameは、"mode"で指定した競合時のファイルの自動生成を、行うかどうかを指定します。
PWEditorでは"常に上書き"のため、falseを指定しています。

clientModifiedはファイルのタイムスタンプを指定します。
nilの場合、Dropbox上にファイルが書き込まれた時刻になります。
タイムスタンプを指定した場合、指定されたタイムスタンプが記録されます。

muteは、ファイルの更新通知を行うかどうかの指定になります。

/**
 ファイルを更新します。
 
 - Parameter filePathName: ファイルパス名
 - Parameter fileData: ファイルデータ
 */
func saveFile(filePathName: String, fileData: Data) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了する。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    // Dropbox上のファイルを更新します。
    // PWEditorでは常に上書き保存になります。
    let _ = client.files.upload(path: filePathName, mode: .overwrite, autorename: false, clientModified: nil, mute: false, input: fileData).response { response, error in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        guard let response = response else {
            // レスポンスがない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // 正常終了の場合の処理を記述してください。
    }
}

API Reference
uploadメソッド
mode(WriteMode)

目次へ

3. おわりに

おそらくDropboxの想定は、

  1. ファイルは一旦デバイス側にダウンロードする。
  2. ファイルの更新はデバイス側の一時ファイルに対して行う。
  3. 最後にアップロードする。

なのではないかと思います。
PWEDitorはDropbox上のファイルを直接編集できるイメージにしているため、ファイルデータはメモリに展開し、更新時に毎回アップロードしています。
そのためネットワーク負荷はそれなりにかかります。

キャッチコピー

目次へ

PWEditor:SwiftのDropbox APIでファイルデータを取得する。

目次

  1. はじめに
  2. ファイルデータ取得処理
  3. おわりに

作って学ぶ iPhoneアプリの教科書 【Swift4&Xcode 9対応】 ~人工知能アプリを作ってみよう! ~(特典PDF付き)

作って学ぶ iPhoneアプリの教科書 【Swift4&Xcode 9対応】 ~人工知能アプリを作ってみよう! ~(特典PDF付き)

1. はじめに

ファイルデータを取得する処理はダウンロードの機能で行います。
Dropbox APIのダウンロード機能は、ファイルデータのみを取得するのではなく、ファイル自体をダウンロードする機能のようです。
PWEditorでは他のストレージとの動作に合わせ、ファイルデータはメモリで保持し、更新時にファイルデータをアップロードする仕様にしています。 そのためDropboxの場合、ファイルデータはいったん一時ファイルとしてファイルをダウンロードして、そのファイルをメモリに展開することにしました。

目次へ

2. ファイルデータ取得処理

ファイルデータを取得する処理は次の手順になります。

  1. 一時ファイルのダウンロードURL(ファイル名)を生成します。
  2. 一時ファイルをダウンロードします。
  3. 一時ファイルがダウロードできたら、ファイルデータをメモリに展開します。
  4. 一時ファイルを削除します。

PWEditorでは、この後ファイルデータがテキストデータかチェックして、テキストデータに変換していますが、サンプルでは省略します。

/**
 ファイルパス名で示されるファイルデータを取得します。
 
 - Parameter filePathName: ファイルパス名
 */
func getFileData(filePathName: String) {
    gaurd let client = DropboxClientManager.authorizedClient else {
        // 認証済みクライアントオブジェクトが取得できない場合、処理を終了します。
        // 念のためのチェックです。
        // 必要ならばエラー処理してください。
        return
    }

    // 一時ファイル用のダウンロード先URLを取得します。
    // 一時ファイルはユーザがアクセスする領域にダウンロードされます。
    // そのためユーザが作成するファイル名と重複しないように
    // ファイル名の先頭にUUIDを付加しています。
    let destination : (URL, HTTPURLResponse) -> URL = { temporaryURL, response in
        let fileManager = FileManager.default
        let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let UUID = Foundation.UUID().uuidString
        var fileName = ""
        if let suggestedFilename = response.suggestedFilename {
            fileName = suggestedFilename
        }
        let pathComponent = "\(UUID)-\(fileName)"
        return directoryURL.appendingPathComponent(pathComponent)
    }

    // ファイルをダウンロードします。
    // filePathNameはDropbox上のファイルパス名です。
    // destinationが一時ファイルのダウンロード先になります。
    let _ = client.files.download(path: filePathName, destination: destination).response { response, error in
        if let error = error {
            // エラーの場合、処理を終了します。
            // 必要ならばエラー処理してください。
            return
        }

        guard let response = response else {
            // レスポンスがない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        guard let (metadata, url) = response else {
            // レスポンスデータがファイル情報ではない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // ファイル属性情報を取得します。
        // ファイル属性情報が必要ならば、fileMetadataから取得してください。
        if type(of: metadata) != Files.FileMetadata.self {
            // ファイル属性情報ではない場合、処理を終了します。
            // 必要ならばエラー処理してください。
            reutrn
        }
        let fileMetadata = metadata as Files.FileMetadata

        // ダウンロードしたファイルからファイルデータを取得し、メモリに展開します。
        let data: Data?
        do {
            data = try Data(contentsOf: url)
        } catch {
            data = nil
        }

         // この時点で一時ファイルは不要になります。
     // そのためこのタイミングで、一時ファイルを削除しておきます(処理は省略します)

        // ファイルデータが取得できたかチェックします。
        guard let fileData = data else {
            // ファイルデータが取得できない場合、処理を終了します。
            // 念のためのチェックです。
            // 必要ならばエラー処理してください。
            reutrn
        }

        // 正常終了の場合の処理を記述してください。
        // 取得したファイルデータはData型のため、ファイルの内容に合わせて適切に変換してください。
        // PWEditorでは、
        //  ①ファイルデータがテキストデータかチェックする。
        //  ②テキストデータに変換する。
        // を行なっています。
    }
}

API Refernce
downloadメソッド

目次へ

3. おわりに

最初はDropboxから直接ファイルデータを取得する方法を探しましたが、見つかりませんでした。
苦肉の策で、一時ファイルをダウンロードして、メモリに展開する仕様にしました。
この方法でもいいのですが、一時ファイルはユーザが使用する領域にできるため、ユーザのファイルと重複する可能性が捨てきれません。
また何かのタイミングで一時ファイルが残ってしまう可能性もあり、できれば他の方法にしたかったです。

念のため、PWEditorではアプリ起動時に何らかの原因で残ってしまった一時ファイルを削除するようにしています。

[改訂新版]Swiftポケットリファレンス (POCKET REFERENCE)

[改訂新版]Swiftポケットリファレンス (POCKET REFERENCE)

TECH::EXPERT

目次へ