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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

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

Swift

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

Q&A

解決済

5回答

1740閲覧

if let 条件分岐が常にfalseになる。

AppDvl

総合スコア58

Xcode

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

Swift

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

0グッド

0クリップ

投稿2019/06/08 16:13

編集2019/06/12 13:17

下記のcodeのfunc loadImage()で条件分岐をしています。

該当のソースコード(urlをStringに変換した)

func loadImage(){ // ③UserDefaultsの情報を参照してpath指定に使う guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし print("(url.absoluteString)を探しています。") if let image = UIImage(contentsOfFile: url.absoluteString) { let image = UIImageView(image: image) imageView.image = image.image imageView.contentMode = UIView.ContentMode.scaleAspectFill print("指定されたファイルが見つかりました") }else{ print("指定されたファイルが見つかりません") } }

これ→**( if let image = UIImage(contentsOfFile: path))**が常にfalseになってuserDefaultsでファイルパスを保存したJPEGが呼び出せません。
JPEGをimageView.image に 入れたいです。

直前のprintアウトでpathを出力すると”保存先のpahtは**file:///var/mobile/Containers/Data/Application/6B28AC39-64FF-4E4E-BE45-19FA15297AB6/Documents/photo2.jpgを探しています。**が表示されるのでパスは保存できています。
ドキュメントフォルダも確認しましたがphoto2.jpgは存在しています。

イメージ説明

呼び出し方がおかしいのでしょうか?
保存したJPEGをimageView.image を表示する方法を教えてください。

初歩的なことかもしれないけど悩んでいます。
どなたかご教授ください、お願いします。

プリントアウト

2019-06-10 20:32:48.277909+0900 Wood volume[15167:2836174] [Accessibility] ****************** Loading GAX Client Bundle **************** file:///var/mobile/Containers/Data/Application/6B28AC39-64FF-4E4E-BE45-19FA15297AB6/Documents/photo2.jpgを探しています。 指定されたファイルが見つかりません 2019-06-10 20:32:57.491298+0900 Wood volume[15167:2836174] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2019-06-10 20:32:57.494345+0900 Wood volume[15167:2836174] [MC] Reading from public effective user settings. pathを作りました。pathはfile:///var/mobile/Containers/Data/Application/6B28AC39-64FF-4E4E-BE45-19FA15297AB6/Documents/photo2.jpg 写真はfile:///var/mobile/Containers/Data/Application/6B28AC39-64FF-4E4E-BE45-19FA15297AB6/Documents/photo2.jpgに保存されました。 file:///var/mobile/Containers/Data/Application/6B28AC39-64FF-4E4E-BE45-19FA15297AB6/Documents/photo2.jpgを探しています。 指定されたファイルが見つかりません

発生している問題・エラーメッセージ

エラーは出ていません

試したこと

試しに !=nil に書き換えても結果はfalseでした。

試しにif let の箇所を下記のように書き換えてみました。

func loadImage(){ // ③UserDefaultsの情報を参照してpath指定に使う guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし print("(url.absoluteString)を探しています。") let a:String? = "Swift" if let test = a { // if let image = UIImage(contentsOfFile: url.absoluteString) { // let image = UIImageView(image: image) // imageView.image = image.image // imageView.contentMode = UIView.ContentMode.scaleAspectFill print("指定されたファイルが見つかりました") }else{ print("指定されたファイルが見つかりません") }

結果(プリントアウト)は
file:///var/mobile/Containers/Data/Application/7EBE7926-90A7-4190-9CF8-6B2D14CB6244/Documents/photo2.jpgを探しています。
指定されたファイルが見つかりました

となります。当然ですが。

ソース全文

// // MemoViewController.swift // Wood volume // // Created by MBP13 on 2019/05/09. // Copyright © 2019 Tomoyuki Ashikari. All rights reserved. // import UIKit import MapKit class MemoViewController: UIViewController ,UIImagePickerControllerDelegate,UINavigationControllerDelegate { @IBOutlet weak var saveButton: UIBarButtonItem! var memo: String?//saveボタン用 // @IBOutlet weak var map: MKMapView! @IBOutlet weak var memoTextField: UITextField! @IBOutlet weak var imageView: UIImageView! @IBAction func launchCamera(_ sender: UIButton) { let camera = UIImagePickerController.SourceType.camera //入力方法を指定し代入 if UIImagePickerController.isSourceTypeAvailable(camera){ //カメラ機能があるか確認 let picker = UIImagePickerController() //モーダルビューコントローラーの作成 picker.sourceType = camera //入力方法cameraをモーダルビューコントローラーに指定 picker.delegate = self self.present(picker,animated: true)//前に出す } } @IBOutlet weak var map: MKMapView! //写真を撮影した後の処理 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info : [UIImagePickerController.InfoKey : Any]){//写真を辞書infoに格納する let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage // キーを使って辞書infoからオリジナル画像を取り出す self.imageView.image = image // let coordinate = info[UIImagePickerController.InfoKey.mediaMetadata] as! String //メタデータ // print(coordinate) UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil)//アルバムに保存 self.dismiss(animated: true)//モーダルビューを非表示に } //保存から呼び出し〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 // ①パスの生成 //UserDefaults のインスタンス生成 let userDefaults = UserDefaults.standard // ドキュメントディレクトリの「ファイルURL」(URL型)定義 var documentDirectoryFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] // ドキュメントディレクトリの「パス」(String型)定義 let filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] //②保存するためのパスを作成する func createLocalDataFile() { // 作成するテキストファイルの名前 let fileName = "photo(cells).jpg" // DocumentディレクトリのfileURLを取得 if documentDirectoryFileURL != nil { // ディレクトリのパスにファイル名をつなげてファイルのフルパスを作る let path = documentDirectoryFileURL.appendingPathComponent(fileName) documentDirectoryFileURL = path print("pathを作りました。pathは(documentDirectoryFileURL)") } } //画像を保存する関数の部分 func saveImage() { createLocalDataFile() //pngで保存する場合 let jpeImageData = imageView.image!.jpegData(compressionQuality: 0.5 ) do { try jpeImageData!.write(to: documentDirectoryFileURL) //②「Documents下のパス情報をUserDefaultsに保存する」 userDefaults.set(documentDirectoryFileURL, forKey: "userImage") let path = String(describing: UserDefaults.standard.url(forKey: "userImage")) print("写真は(path)に保存されました。") } catch { //エラー処理 print("エラー") } } func loadImage(){ // ③UserDefaultsの情報を参照してpath指定に使う guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし print("(url.absoluteString)を探しています。") if let image = UIImage(contentsOfFile: url.absoluteString) { let image = UIImageView(image: image) imageView.image = image.image imageView.contentMode = UIView.ContentMode.scaleAspectFill print("指定されたファイルが見つかりました") }else{ print("指定されたファイルが見つかりません") } } //〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜保存から呼び出し override func viewDidLoad() { super.viewDidLoad() //文字が入力されるまでsaveButtonを使わない //self.saveButton.isEnabled = false //タイトルを変える self.navigationItem.title = "Edit Memo" //値を受け取る //Optional Binding を使ってあげて、 if let memo = self.memo で memo に self.memo をセットしつつ、もし値がセットされていたら、 textField に memo を渡してあげれば OK if let memo = self.memo{ self.memoTextField.text = memo } self.updateSaveButtonState() // Do any additional setup after loading the view, typically from a nib. loadImage() } private func updateSaveButtonState(){ let memo = self.memoTextField.text ?? "" //memoがnilだったら空文字 self.saveButton.isEnabled = !memo.isEmpty //saveButtonnが有効なのはsaveButtonが空でないとき } //textField に入力された値を検出 //textField を Control + クリックすると Editing Changed //という項目があるので、これをこのあたりにドラッグしてあげてメソッドを作っていきます。 //extField の中身が変わった時の処理をこちらに書くことができます。 @IBAction func memoTextFieldChanged(_ sender: Any) { updateSaveButtonState() } @IBAction func cancel(_ sender: Any) { // self.dismiss(animated: true, completion: nil) if self.presentingViewController is UINavigationController { self.dismiss(animated: true, completion: nil) } else { self.navigationController?.popViewController(animated: true) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //saveボタンが押されたときの処理だったらsenderに入ってくるのでguardでチェック //ボタンアイテムでキャストする //saveボタンと同じか比較する //そうじゃなかったらreturnでとめる //これでセグエが巻き戻る時に値がセットされる override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard let button = sender as? UIBarButtonItem, button === self.saveButton else { return } self.memo = self.memoTextField.text ?? "" saveImage() } }

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

UIImage(contentsOfFile: 〜)の引数に指定できるのはURLではなくpathです。
url.absoluteStringは、URLを文字列にしたものであり、pathではありません。

swift

1if let image = UIImage(contentsOfFile: url.path) {

と書けば正しく読めると思います。
(takabosoftさんやdsuzukiさんがアドバイスされていたアンラップ処理
guard let url = UserDefaults.standard.url(forKey: "userImage") else { return }
は、その前提として必要です。)

投稿2019/06/12 15:13

編集2019/06/12 15:44
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AppDvl

2019/06/13 10:04

TakeOneさん ありがとうございます。 アドバイスの通り書き直したら 指定されたファイルが見つかりました 2019-06-13 18:53:35.718813+0900 Wood volume[17130:3248719] Could not load IOSurface for time string. Rendering locally instead. となり、imageViewにも読み込めています。 文字列にすれば良いと思い違いをしていたので、大変勉強になりました。 重ねて感謝したします。
guest

0

UserDefaultにimageのpashを保存している部分があると思うのですが、保存している部分ではUIImageを作成することができていますか?

投稿2019/06/12 06:56

harumi

総合スコア407

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AppDvl

2019/06/12 13:14

回答いただきありがとう御座います。 ご指摘のところを下記に変え、一番下でbreakPOINTで止めました。 ちなみに if let image = UIImage(contentsOfFile: documentDirectoryFileURL.absoluteString) の documentDirectoryFileURL.absoluteString を path にしても結果は同じでした。 原因が3日悩んでいますが、全くわかりません。 結果、プリントアウトでも「指定されたファイルが存在しません。」 となります。 ただ、UIimageは写真の通り保存できています。 2019-06-12 22:03:29.669117+0900 Wood volume[16740:3144469] [Accessibility] ****************** Loading GAX Client Bundle **************** file:///var/mobile/Containers/Data/Application/C8CBCB78-89E8-482F-A248-36CDF17759BA/Documents/photo2.jpgを探しています。 指定されたファイルが見つかりません 2019-06-12 22:03:32.674460+0900 Wood volume[16740:3144469] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2019-06-12 22:03:32.675890+0900 Wood volume[16740:3144469] [MC] Reading from public effective user settings. pathを作りました。pathはfile:///var/mobile/Containers/Data/Application/C8CBCB78-89E8-482F-A248-36CDF17759BA/Documents/photo2.jpg 指定されたファイルが存在しません。 (lldb) let jpeImageData = imageView.image!.jpegData(compressionQuality: 1.0 ) do { try jpeImageData!.write(to: documentDirectoryFileURL) //②「Documents下のパス情報をUserDefaultsに保存する」 userDefaults.set(documentDirectoryFileURL, forKey: "userImage") let path = String(describing: UserDefaults.standard.url(forKey: "userImage")!) if let image = UIImage(contentsOfFile: documentDirectoryFileURL.absoluteString){ print("指定されたファイルの存在を確認しました。") }else{ print("指定されたファイルが存在しません。") } // print("写真は(path)に保存されました。") } catch { //エラー処理 print("エラー") } }
guest

0

pathの出力に "Optional("と")" が含まれているのが問題ではないでしょうか。
UserDefaults.standard.url(forKey: "userImage")をアンラップしてもダメでしょうか。

投稿2019/06/10 01:36

dsuzuki

総合スコア1682

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AppDvl

2019/06/10 12:50

ご回答頂きありがとうございます。 Stringにしても結果はfalseでした。 xcodeのWindowのdevice and simulatorsでDownloadcontainerから「パッケージの内容を確認する」で保存しているjpegは存在しているのですが。
guest

0

こんにちは。

let path = String(describing: UserDefaults.standard.url(forKey: "userImage"))

この書き方だと

Optional(file:///var/mobile/Containers/Data/Application/143D63DA-BEEC-4BE8-9E10-4F1609E6B48C/Documents/photo2.jpg)

と出ているようにOptional(file://...)と入ってしまって正式なパスとしてみなされません。

URLをStringにするにはいくつか方法があった気がしますが、

guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし
print("(url.absoluteString)を探しています。")
if let image = UIImage(contentsOfFile: url.absoluteString) {

とかでどうですかね?

投稿2019/06/10 01:21

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AppDvl

2019/06/10 12:30 編集

ご回答いただきありがとうございます。 アドバイスの通り書き換えてみましたが結果はfalseになります。 試しにif let の箇所を下記のように書き換えてみあました。 func loadImage(){ // ③UserDefaultsの情報を参照してpath指定に使う guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし print("(url.absoluteString)を探しています。") let a:String? = "Swift" if let test = a { // if let image = UIImage(contentsOfFile: url.absoluteString) { // let image = UIImageView(image: image) // imageView.image = image.image // imageView.contentMode = UIView.ContentMode.scaleAspectFill print("指定されたファイルが見つかりました") }else{ print("指定されたファイルが見つかりません") } 結果(プリントアウト)は file:///var/mobile/Containers/Data/Application/7EBE7926-90A7-4190-9CF8-6B2D14CB6244/Documents/photo2.jpgを探しています。 指定されたファイルが見つかりました となります。当然ですが。 保存されているjpegを確認する方法はxcodeのWindowのdevice and simulatorsでDownloadcontainerで行ってますが、これで良いのでしょうか? なぜnilと判断されるのか全くわかりません。
guest

0

TakeOneさん他、皆さんのアドバイスの通りに書き直したらうまくいきました。
開発初心者の方々の参考の為に下記に修正したcodeを記載します。

// ①パスの生成 //UserDefaults のインスタンス生成 let userDefaults = UserDefaults.standard // ドキュメントディレクトリの「ファイルURL」(URL型)定義 var documentDirectoryFileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] // ドキュメントディレクトリの「パス」(String型)定義 let filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] //②保存するためのパスを作成する func createLocalDataFile() { // 作成するテキストファイルの名前 let fileName = "photo(cells).jpg" // DocumentディレクトリのfileURLを取得 if documentDirectoryFileURL != nil { // ディレクトリのパスにファイル名をつなげてファイルのフルパスを作る let path = documentDirectoryFileURL.appendingPathComponent(fileName) documentDirectoryFileURL = path print("pathを作りました。pathは(documentDirectoryFileURL)") } } //画像を保存する関数の部分 func saveImage() { createLocalDataFile() //保存 let jpeImageData = imageView.image!.jpegData(compressionQuality: 1.0 ) do { try jpeImageData!.write(to: documentDirectoryFileURL) //②「Documents下のパス情報をUserDefaultsに保存する」 userDefaults.set(documentDirectoryFileURL, forKey: "userImage") let path = String(describing: UserDefaults.standard.url(forKey: "userImage")!) print("写真は(path)に保存されました。") } catch { //エラー処理 print("エラー") } } func loadImage(){ // ③UserDefaultsの情報を参照してpath指定に使う guard let url = UserDefaults.standard.url(forKey: "userImage") else { return } // URL取得なし if let image = UIImage(contentsOfFile: url.path){ print("url.pathは(url.path)") let imagep = UIImageView(image: image) imageView.image = imagep.image imageView.contentMode = UIView.ContentMode.scaleAspectFill print("指定されたファイルが見つかりました") }else{ print("指定されたファイルが見つかりません") } }

投稿2019/06/13 10:09

AppDvl

総合スコア58

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問