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

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

ただいまの
回答率

90.34%

  • Swift

    9429questions

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

  • Xcode

    5303questions

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

  • iOS

    4960questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

swift3 撮った写真データをテキストと一緒にiCloudに保存したい。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 975

t.harima

score 45

カメラで撮った写真を書き込みキーでiCloudにアップして、読み込みキーでiCloudからダウンロードして、imageに表示したい。保存形式は、ドキュメント方式です。

//
// ViewController.swift
//


import UIKit

//iCloud
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    //定数
    let BTN_WRITE1 = 2 //書き込み1
    let BTN_READ1 = 3  //読み込み1

    //変数
    var _textField1: UITextField! //テキストフィールド1
    var _textField3: UITextField! //テキストフィールド2

    @IBOutlet weak var imageView: UIImageView!


    @IBAction func launchCamera(_ sender: UIBarButtonItem) {
        let camera = UIImagePickerControllerSourceType.camera

        if UIImagePickerController.isSourceTypeAvailable(camera) {
            let picker = UIImagePickerController()
            picker.sourceType = camera
            picker.delegate = self
            self.present(picker,animated: true)
        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        self.imageView.image = image
        UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        self.dismiss(animated: true)
    }


//====================
//UI
//====================
    //ロード完了時に呼ばれる
    override func viewDidLoad() {
        super.viewDidLoad()

        let dx: CGFloat = (UIScreen.main.bounds.size.width-320)/2


        //ドキュメントのUIの生成
        _textField1 = makeTextField(CGRect(x: dx+10, y: 140, width: 200, height: 32), text: "")
        self.view.addSubview(_textField1)
        let btnWrite1 = makeButton(CGRect(x: dx+10, y: 190, width: 190, height: 40),
            text: "ドキュメントの書き込み", tag: BTN_WRITE1)
        self.view.addSubview(btnWrite1)
        let btnRead1 = makeButton(CGRect(x: dx+210, y: 190, width: 90, height: 40),
            text: "読み込み", tag: BTN_READ1)
        self.view.addSubview(btnRead1)
    }

    //ボタンクリック時に呼ばれる
    func onClick(_ sender: UIButton) {
        if sender.tag == BTN_WRITE1 {
            DispatchQueue.global().async(execute: {
                let icloudURL = self.makeICloudURL("img_test")
                DispatchQueue.main.async(execute: {
                    if icloudURL != nil {
                        self.writeICloud1(icloudURL!)
                    } else {
                        self.showAlert("エラー", text: "iCloudのURLの取得に失敗")
                    }
                })
            })
        } else if sender.tag == BTN_READ1 {
            DispatchQueue.global().async(execute: {
                let icloudURL = self.makeICloudURL("img_test")
                DispatchQueue.main.async(execute: {
                    if icloudURL != nil {
                        self.readICloud1(icloudURL!)
                    } else {
                        self.showAlert("エラー", text: "iCloudのURLの取得に失敗")
                    }
                })
            })
        }
    }

    //テキストフィールドの初期化
    func makeTextField(_ frame: CGRect, text: String) -> UITextField {
        let textField = UITextField()
        textField.frame = frame
        textField.text = text
        textField.borderStyle = UITextBorderStyle.roundedRect
        textField.keyboardType = UIKeyboardType.default
        textField.returnKeyType = UIReturnKeyType.done
        textField.delegate = self
        return textField
    }

    //テキストボタンの初期化
    func makeButton(_ frame: CGRect, text: String, tag: Int) -> UIButton {
        let button = UIButton(type: UIButtonType.system)
        button.frame = frame
        button.setTitle(text, for: UIControlState())
        button.tag = tag
        button.addTarget(self, action: #selector(onClick(_:)),
            for: UIControlEvents.touchUpInside)
        return button
    }

    //アラートの表示
    func showAlert(_ title: String?, text: String?) {
        let alert = UIAlertController(title: title, message: text,
            preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "OK",
            style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }

//====================
//iCloud
//====================

    //iCloudのドキュメントのURLの生成(3)
    func makeICloudURL(_ fileName: String) -> URL? {
        //iCloudのディレクトリのURLの生成
        let fileManager = FileManager.default
        let icloudURL = fileManager.url(forUbiquityContainerIdentifier: nil)
        if let docURL = icloudURL?.appendingPathComponent("Documents") {
            //ディレクトリがない時は生成
            if fileManager.fileExists(atPath: docURL.path) == false {
                do {
                    try fileManager.createDirectory(at: docURL,
                        withIntermediateDirectories: true,
                        attributes: nil)
                } catch _ {
                }
            }

            //iCloudのドキュメントのURLを返す
            return docURL.appendingPathComponent(fileName)
        }
        return nil
    }

    //iCloudへのドキュメントの書き込み(4)
    func writeICloud1(_ icloudURL: URL) {
        let document = ICloudDocument(fileURL: icloudURL)
        document.text = _textField1.text!
        document.save(to: icloudURL,
            for: UIDocumentSaveOperation.forCreating,
            completionHandler: {(success: Bool) in
                 print("write document>\(success)")
        })
    }

    //iCloudからのドキュメントの読み込み(5)
    func readICloud1(_ icloudURL: URL) {
        let document = ICloudDocument(fileURL: icloudURL)
        document.open(completionHandler: {(success: Bool) in
            print("read document>\(success)")
            self._textField1.text = document.text
        })
    }

//====================
//UITextFieldDelegate
//====================
    //改行ボタン押下時に呼ばれる
    func textFieldShouldReturn(_ sender: UITextField) -> Bool {
        //キーボードを閉じる
        self.view.endEditing(true)
        return true
    }
}
//
// ICloudDocument.swift
//

import UIKit

//ドキュメント
class ICloudDocument: UIDocument {
    var text = "" //テキスト

    //ドキュメント読み込み時に呼ばれる(6)
    override func load(fromContents contents: Any, ofType: String?) throws {
        self.text = (NSString(data: contents as! Data,
                              encoding: String.Encoding.utf8.rawValue) as String?)!
    }

    //ドキュメント書き込み時に呼ばれる(7)
    override func contents(forType typeName: String) throws -> Any {
        if let value = self.text.data(using: String.Encoding.utf8) {
            return value
        }
        return Data()
    }
}

イメージ説明

イメージ説明

宜しくお願い申し上げます。

AppDelegate.swiftもアップします。

//
// AppDelegate.swift
//
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow? //ウィンドウ

    //アプリ起動完了時に呼ばれる
    func application(_ application: UIApplication,
        didFinishLaunchingWithOptions
        launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        return true
    }
}


宜しくお願い申し上げます。

swift3での変更点は修正したつもりです。

            let subjectTitle = ["おもち" ,"ごはん","パン"]
            let imgArray : NSMutableArray = []
            for x in 0...subjectTitle.count {
                let filePath = localDocumentsPath + USDocInfo.NAME + "." + USDocInfo.ECTENSION + "." + subjectArray[x]  // <- Use of unresolved identifier ‘subjectArray’ エラー
                let fileUrl = NSURL(fileURLWithPath:filePath)
                //ファイルの存在チェック
                isFileExists = FileManager.default.fileExists(atPath: filePath)
                document = USDocument(fileURL:fileUrl as URL)
//                if isFileExists{
//                    document.open(completionHandler: { (success:Bool) -> Void in
                if isFileExists{
                    let doc:USDocument = self.documentArray[self.x] as! USDocument  // <- Value of typeViewController’ has no member ‘documentArray’ エラー
                    doc.open(completionHandler: { (success:Bool) -> Void in


                        if success{
                            self.imgArray.addObject(self.document.img)  // <- Value of typeViewController’ has no member ‘imgArray’ エラー
                        }else{
                            print("Documentを開けませんでした。")
                        }
                    })
                }else{
                    print("Documentがありませんぬ")
                }
            }


エラーが発生します。大変申し訳ございませんが、今一度ご教授願います。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2017/04/07 13:46

    質問のコードには、写真を保存するコードは含まれていないということでしょうか?

    キャンセル

  • t.harima

    2017/04/07 14:55

    遅くなりまして申し訳ありません。おっしゃる通りで、テキストは保存できているのですが、写真は保存できていません。

    キャンセル

  • t.harima

    2017/04/07 14:56

    写真を保存するコードもありません。

    キャンセル

回答 1

+1

少し調べていたのですが、1つのファイルに1つのデータしか保存出来ないということなんですかね。

複数データをまとめたクラスを作ってData化(シリアライズ)すれば出来そうな気もしますが、NSFileWrapperを使うのが良いようです。

【Swift】NSData/NSFileWrapperを利用してデータを保存する

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/10 16:27

    時間がかかり大変申し訳ありません。作成されたリストをコピーして入力、修正をしているのですが、どうしても、分からないところがあります。
    もう少しお付き合いしていただけないでしょうか?

    //ここで保存したい内容を書く
    // let subjectTitle = "おもち"
    // let filePath = localDocumentsPath + USDocInfo.NAME + "." + USDocInfo.ECTENSION + "." + subjectTitle
    let subjectTitle = ["おもち" ,"ごはん","パン"]
    let imgArray : NSMutableArray = []
    for x in 0...subjectTitle.count {
    let filePath = localDocumentsPath + USDocInfo.NAME + "." + USDocInfo.ECTENSION + "." + subjectArray[x]
    ここで Use of unresolved identifier 'subjectArray' のエラーが発生


    let fileUrl = NSURL(fileURLWithPath:filePath)
    //ファイルの存在チェック
    isFileExists = FileManager.defaultManager().fileExistsAtPath(filePath)
    document = USDocument(fileURL:fileUrl)
    // if isFileExists{
    // document.open(completionHandler: { (success:Bool) -> Void in
    if isFileExists{
    let doc:USDocument = self.documentArray[self.x] as! USDocument
    ここで Value of type 'ViewController' has no member 'documentArray' のエラーが発生


    doc.open(completionHandler: { (success:Bool) -> Void in


    if success{
    self.imgArray.addObject(self.document.img)
    ここで Value of type 'ViewController' has no member 'imgArray' のエラーが発生



    }else{
    print("Documentを開けませんでした。")
    }
    })
    }else{
    print("Documentがありませんぬ")
    }
    }


    あと、つぎの文をどこに入れて良いかわかりません。
    self.myCollectionView.reloadData()

    同じ本を購入して見ているもののまだ理解できません。

    キャンセル

  • 2017/04/10 17:06

    コメント欄に長々とコードを書く人の相手はしません。

    キャンセル

  • 2017/04/11 12:28

    申し訳ございません

    キャンセル

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

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

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

  • Swift

    9429questions

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

  • Xcode

    5303questions

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

  • iOS

    4960questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。