前提・実現したいこと
以下のコードを実装した後、発生するエラーに関して質問があります。
仮に、遷移元の画面をA、このコードが書かれている画面をBとします。
以下のコードは、**「B画面にて、Firebaseから特定の値を削除し、self.navigationController?.popViewController(animated: true)で、遷移元の画面(A)に戻る処理」**を実装しています。
このコードにより、確かにfirebase上の値は削除され、遷移元の画面(A)には戻るのですが、
その後、**何故か、「既に遷移して、シュミレーターの画面も切り替わっているのにB画面のファイルでエラーが発生」**してしまいます!!
swift
1class SubliminalShowViewController: UIViewController { 2 3 4 5 //MARK:parts===================================== 6 @IBOutlet weak var tableView: UITableView! 7 8 9 //MARK:変数======================================== 10 //MARK:categoryIndex → RecategoryShowから引き継いだ一つのcategoryのインスタンス 11 var categoryArray = [Categorys]() 12 //MARK:RecategoryShowに紐付くsubliminalID(前画面からの引継ぎ) 13 var subliminalID = String() 14 //MARK:subliminalIDを元に、Firebaseからの取得したsubliminalの情報(tableViewで利用) 15 var subliminalArray = [Subliminals]() 16 //MARK:subliminals/autoID/categoryID群の配列(subliminalArrayから取得) 17 var subliminaRelationCategorysArray = [String:Bool]() 18 //MARK:subliminaRelationCategorysArrayの連想配列型から、keyだけ取得 19 var subliminaRelationCategorysKeyArray = [String]() 20 //MARK:subliminalに紐付いている写真の枚数(追加したphotoをFirebaseに保存する時に使用) 21 var subliminalPhotosCount = Int() 22 23 24 //MARK:初期設定 25 override func viewDidLoad() { 26 super.viewDidLoad() 27 } 28 29 30 31 //MARK:毎回 32 override func viewWillAppear(_ animated: Bool) { 33 super.viewWillAppear(animated) 34 print("0.categoryArray(このsubliminalが所属しているcategoyのautoID)==================") 35 print(self.categoryArray[0].categoryID) 36 print("1.categoryArray(所属しているカテゴリー名)=====================================") 37 print(self.categoryArray[0].categoryTitle) 38 print("2.subliminalID(表示しているsubliminalのID)====================================") 39 print(self.subliminalID) 40 settingTableView() 41 settingNavigation() 42 settingUINib() 43 fetchSubliminalData() 44 } 45 46 47 48 49 //MARK:setting================================== 50 //MARK:tableView 51 func settingTableView(){ 52 self.tableView.delegate = self 53 self.tableView.dataSource = self 54 //MARK:未使用のCellを消去 55 tableView.tableFooterView = UIView() 56 //MARK:Cell上のButtonの遅延を無くす 57 tableView.delaysContentTouches = false 58 59 } 60 61 62 63 //MARK:action===================================== 64 65 66 //MARK:「削除」Button 67 @objc func showAlertForDelete(){ 68 let alertController = UIAlertController(title: "Subliminalの削除", message: "本当に削除してもよろしいですか?", preferredStyle: .alert) 69 let action1 = UIAlertAction(title: "キャンセル", style: .cancel) { (alert) in 70 } 71 let action2 = UIAlertAction(title: "削除", style: .destructive) { (alert) in 72 self.deleteSubliminal() 73 } 74 alertController.addAction(action1) 75 alertController.addAction(action2) 76 self.present(alertController, animated: true, completion: nil) 77 } 78 79 80 81 82 83 84 85 86 87 88 89 //MARK:method=================================== 90 //MARK:FirebaseからSubliminalの情報を収集 91 //MARK:この場合、Subliminalは一つだけ取得 92 func fetchSubliminalData(){ 93 //MARK:subliminal配下の一意のautoIDまでreferenceを取得 94 let subliminalRef = Database.database().reference().child("subliminals").child("(subliminalID)") 95 //MARK:reference配下の情報を塊にして取得 96 subliminalRef.observe(.value) { [self] (snapShot) in 97 //MARK:通信が終わったら呼ばれる 98 //MARK:snapShotからdataを引き出す 99 let snapShotData = snapShot.value as AnyObject 100 //MARK:取得したデータから、keyでvalueを取得(この段階では何型か判断出来ない) 101 let subliminalId = snapShotData.value(forKey: "subliminalId") 102 let subliminalTitle = snapShotData.value(forKey: "subliminalTitle") 103 let subliminalTitleImage = snapShotData.value(forKey: "subliminalTitleImage") 104 let subliminalDescription = snapShotData.value(forKey: "subliminalDescription") 105 let subliminalPhotos = snapShotData.value(forKey: "subliminalPhotos") 106 let categoryID = snapShotData.value(forKey: "categoryID") 107 //MARK:空判定する方法 108 var postDate:CLong? 109 if let postedDate = snapShotData.value(forKey: "postData") as? CLong{ 110 postDate = postedDate 111 }else{ 112 print("kara") 113 } 114 115 //MARK:postDataを時間に変換 116 let timeString = self.convertTimeStamp(serverTimeStamp: postDate!) 117 //MARK:Subliminalsモデルのインスタンスを生成(ここでダウンキャストしている) 118 let subliminal = Subliminals( 119 subliminalTitle: subliminalTitle as! String, 120 subliminalTitleImage: subliminalTitleImage as! String, 121 subliminalId: subliminalId as! String, 122 subliminalDescription: subliminalDescription as! String, 123 subliminalPhotos: subliminalPhotos as! Array<Any>, 124 postData: timeString, 125 categoryID: categoryID as! [String : Bool] 126 ) 127 //MARK:配列の中を空へ 128 self.subliminalArray.removeAll() 129 //MARK:配列へSubliminalsモデルのinstanceを格納(tableViewで利用) 130 self.subliminalArray.append(subliminal) 131 //MARK:廃列へ格納したインスタンスから、subliminalPhotosの数を取得(新しくsubliminalPhotosをFirebaseに追加する時に利用する(Firebase保存で利用)) 132 self.subliminalPhotosCount = self.subliminalArray[0].subliminalPhotos!.count 133 print("3.subliminalPhotosCount=======================") 134 print(subliminalPhotosCount) 135 //MARK:subliminalが所有しているcategoryIDの連想配列群を取得 136 self.subliminaRelationCategorysArray = self.subliminalArray[0].categoryID 137 //MARK:subliminaRelationCategorysArrayの連想配列群から、keyだけを配列化 138 self.subliminaRelationCategorysKeyArray.append(contentsOf: subliminaRelationCategorysArray.keys) 139 print("4.subliminalが所属しているCategoryのautoID群=======================") 140 print(subliminaRelationCategorysKeyArray) 141 self.tableView.reloadData() 142 } 143 } 144 145 146 147 148 //MARK:時間を人間が読める形に変換する 149 func convertTimeStamp(serverTimeStamp:CLong) -> String{ 150 let x = serverTimeStamp / 1000 151 let date = Date(timeIntervalSince1970: TimeInterval(x)) 152 let formatter = DateFormatter() 153 formatter.dateStyle = .long 154 formatter.timeStyle = .medium 155 return formatter.string(from: date) 156 } 157 158 159 160 161 162 163 //MARK:選択した画像を、Firebase/subliminals/subliminalPhotosに保存 164 func updataSubliminalPhotos(selectedImage:UIImage){ 165 //MARK:リファレンスの形成==================================== 166 //MARK:subliminals/autoID/subliminalPhotos迄のreference取得 167 let subliminalPhotoRef = Database.database().reference().child("subliminals").child("(subliminalID)").child("subliminalPhotos") 168 //MARK:Storageのreference取得 169 let storage = Storage.storage().reference(forURL: "gs://subliminalapp-1936e.appspot.com") 170 //MARK:Storageへ保存の為のkeyを作成(必須ではない) 171 let key = subliminalPhotoRef.child("subliminalPhotos").childByAutoId() 172 //MARK:StorageServerにパスを形成 173 let imageRef = storage.child("SubliminalImageView").child("(String(describing: key)).jpg") 174 175 176 //MARK:画像をデータ型へ変換================================== 177 //MARK:Data()のinstance 178 var subliminalImageViewData:Data = Data() 179 //MARK:圧縮データを作成 180 subliminalImageViewData = (selectedImage.jpegData(compressionQuality: 0.01))! 181 182 183 184 185 //MARK:画像をStorageへ保存================================== 186 let uploadTask = imageRef.putData(subliminalImageViewData, metadata: nil) { (metadata, error) in 187 //MARK:エラー処理 188 if error != nil{ 189 print(error as Any) 190 return 191 } 192 print("Storage保存成功!!") 193 //MARK:成功時(urlを取得) 194 imageRef.downloadURL { (url, error) in 195 //MARK:エラー処理 196 if error != nil{ 197 print(error as Any) 198 return 199 } 200 print("downloadURL成功") 201 //MARK:成功時(databaseへ値を保存) 202 subliminalPhotoRef.updateChildValues([ String(self.subliminalPhotosCount) : url?.absoluteString as Any]) 203 } 204 } 205 }
発生している問題・エラーメッセージ
swift
1 //MARK:postDataを時間に変換 2 let timeString = self.convertTimeStamp(serverTimeStamp: postDate!) 3 4 ここで以下のエラーが発生してしまいます。 5 「Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value」 6
回答1件
あなたの回答
tips
プレビュー