本件で3週間詰まってしまっており、お力添え頂けますと大変幸いです。
【実現したいこと】
メッセージアプリを作っています。
基本的な処理の流れは下記の通りです。
1.各友達との個別のトーク画面を開く
2.Firebaseからその友達とのメッセージ情報を取得し、カスタムクラスの配列に代入
3-a.Collection Viewのセルをタップすると、カスタムクラスから該当の情報を取得し再生
3-b.iPhoneのProximity Sensorが発動した際も、3-aと同様に、画面に表示されているセルの音声を自動再生(1画面に表示されるセルは1つのみ。)
【問題点】
3-a.は問題なく処理できますが、3-b.でつっかかっています。アプリを起動し、最初に開いたトーク画面で処理をする分には上手くいきますが、一度個別トークルームを出てから、もう一度そのトークルーム、あるいは別の友達のトークルームに行ってからProximity Sensorを発動すると、正しいメッセージと、先ほどいたトークルームのメッセージの2つが同時に再生されてしまいます。message配列は個別トークルームを開くたびに作り直されると思っていましたが、なぜか前回入ったトークルームの情報を踏襲してしまっています。踏襲した上で、新しい方のトークルームの情報も追加されるという謎現象です。
Swift
1 @objc func proximitySensorStateChanged(){ 2 print(messages[1].url) 3 4 if (UIDevice.current.proximityState == true) { 5 do{ 6 let audioSession = AVAudioSession.sharedInstance() 7 do { 8 try audioSession.overrideOutputAudioPort(AVAudioSession.PortOverride.none) 9 } catch let error as NSError { 10 print("audioSession error: (error.localizedDescription)") 11 } 12 let audioUrl = URL(string: messages[self.neo].url!)//self.neoには画面に現在表示されているセルのindexPath.rowの数字が入っています。(別箇所で取得済み)。 13 URLSession.shared.dataTask(with: audioUrl!, completionHandler: { (data, response, error) in 14 DispatchQueue.global().async{ 15 DispatchQueue.main.async{ 16 do { 17 self.audioPlayer = try AVAudioPlayer(data:data!) 18 self.audioPlayer.delegate = self 19 self.audioPlayer.play() 20 } 21 catch{} 22 } 23 } 24 }).resume() 25 } catch { 26 } 27 } 28 } 29
【試してみたこと】
一度入ったトークルームから戻るときに、removeAllでmessage配列を空にしてみました。
Swift
1 @IBAction func backBtn(_ sender: Any) { 2 messages.removeAll() 3 dismiss(animated: true, completion: nil); 4 }
この状態で、もう一度誰かのトークルームに入ると、 promximity sensorの上記コードで記載した一番最初のprint(messages[1].url)がエラーとなりクラッシュしてしまいます。一度messageを空にしても、今回新しいトークルームに入るタイミングでその情報を取得しmessageに入れているはずなのでnilにならないはずなのですが。。。
またこの状態で、以下didselectの中で同じ出力をしてもクラッシュしません。didselectで処理する分には、いろんなトークルームに出入りしようがバグは起きず、ちゃんと該当のメッセージが再生されます。
Swift
1 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 2 print(messages[1].url) 3} 4
なお、Firebaseから情報を取得してカスタムクラスに代入しているコードは以下です。
Swift
1 var messages = [Message]() 2 3//override func viewDidLoad()の中 4 Database.database().reference().child("user-messages").child(uid!).observe(.childAdded, with: { (snapshot) in 5 let messageId = snapshot.key 6 DBProvider.Instance.mediaMessagesRef.child(messageId).observe(.value, with: { (snapshot) in 7 if let d = snapshot.value as? [String:AnyObject]{ 8 if let url = d["url"] as? String { 9 let senderId = d["sender_id"] as? String 10 let toId = d["toID"] as? String 11 let childkey = d["childkey"] as? String 12 let listened = d["listened"] as? Bool 13 let timeStamp = d["timeStamp"] as? NSNumber 14 let newContact = Message(senderId: senderId!, url: url, toId: toId!, timeStamp: timeStamp! , childkey: childkey!, listened: listened!); 15 //自分が送ったボイスかつ、送り先がContactsVCで選んだ友達のとき。 16 if senderId == (Auth.auth().currentUser?.uid)! && toId! == self.toID { 17 self.messages.append(newContact); 18 } 19 //友達が送ったボイスかつ、送り先が自分 20 else if senderId == self.toID && toId == Auth.auth().currentUser?.uid { 21 self.messages.append(newContact); 22 } else { 23 } 24 //自分からそれ以外に送ったボイスや、友達が自分以外に送ったボイスはスルーする。 25 self.messages.sort(by: {Double($0.timeStamp!) < Double($1.timeStamp!)}) 26 } 27 } 28 }, withCancel: nil) 29 }, withCancel: nil) 30 31 32NotificationCenter.default.addObserver(self, selector: #selector(ChatVC.proximitySensorStateChanged), name: UIDevice.proximityStateDidChangeNotification, object: nil) 33
以上、お読みいただきありがとうございます。
アドバイス等ございましたらコメント頂けますと幸いです。よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/17 01:33
2019/09/17 16:00
2019/09/19 15:01
2019/09/19 16:23
2019/09/23 05:19
2019/09/23 08:01
2019/09/28 13:23 編集
2019/09/28 14:02