getting it sort of working but have a freeze

This commit is contained in:
talksik
2022-01-03 18:24:00 -08:00
parent e043c5a745
commit b77ae21973
3 changed files with 71 additions and 26 deletions
+3 -3
View File
@@ -33,7 +33,7 @@ final class AuthSessionStore: ObservableObject, SessionStore {
@Published var sessionState: SessionState = SessionState.notCheckedYet @Published var sessionState: SessionState = SessionState.notCheckedYet
// TODO: figure out which ones to publish // TODO: figure out which ones to publish
var messagesArr: [Message] = [] @Published var messagesArr: [Message] = []
var userFriendsDict: [String: UserFriends] = [:] // all active and inactive relationships var userFriendsDict: [String: UserFriends] = [:] // all active and inactive relationships
// transformed data for the views // transformed data for the views
@@ -337,7 +337,7 @@ extension AuthSessionStore {
// if this user is not already a friend, active or inactive/rejected, then get their user data and add to inbox // if this user is not already a friend, active or inactive/rejected, then get their user data and add to inbox
if self.userFriendsDict.keys.contains(userFriend!.userId) { if self.userFriendsDict.keys.contains(userFriend!.userId) {
print("already have this user in my circle or I rejected them \(userFriend?.userId)") // print("already have this user in my circle or I rejected them \(userFriend?.userId)")
continue continue
} }
else { else {
@@ -383,7 +383,7 @@ extension AuthSessionStore {
self.messagesArr = documents.compactMap { (queryDocumentSnapshot) -> Message? in self.messagesArr = documents.compactMap { (queryDocumentSnapshot) -> Message? in
do { do {
let currMessage = try queryDocumentSnapshot.data(as: Message.self) let currMessage = try queryDocumentSnapshot.data(as: Message.self)
print("new message received! \(currMessage!.sentTimestamp)") // print("new message received! \(currMessage!.sentTimestamp)")
DispatchQueue.main.async { DispatchQueue.main.async {
if currMessage != nil { // not really possible but just check if currMessage != nil { // not really possible but just check
@@ -368,10 +368,15 @@ struct CircleGridView: View {
} }
self.animateLiveConvos = true self.animateLiveConvos = true
}// univseral alert TODO: move to inner circle view and use this pattern for all view models }
// .alert(item: self.$convoVM.error) {error in .onReceive(self.authSessionStore.$messagesArr) {_ in
// error.alert // TODO: don't know if this fires if I am active and I receive a message but that's not something I am allowing right now with the continuous convo feature
// }
print("new messages found!!!! on receive going to cache all messages to load them faster for you!")
// TODO: might be including messages of inbox users? overloading memory?
self.innerCircleVM.cacheIncomingMessages(friendMessagesDict: self.authSessionStore.relevantMessagesByUserDict)
}
} // scrollview reader } // scrollview reader
} }
@@ -71,7 +71,9 @@ class InnerCircleViewModel: NSObject, ObservableObject {
} }
var audioRecorder : AVAudioRecorder! var audioRecorder : AVAudioRecorder!
var queuePlayer = AVQueuePlayer() var queuePlayer = AVQueuePlayer()
private var cachedPlayerItemsDict: [String: Data] = [:] // url to player item
@Published var isRecording : Bool = false @Published var isRecording : Bool = false
@@ -255,15 +257,22 @@ extension InnerCircleViewModel {
// clearing the player to make room for this friend's convo or to deselect this user // clearing the player to make room for this friend's convo or to deselect this user
self.stopPlayingAnyAudio() self.stopPlayingAnyAudio()
var AVPlayerItems: [AVPlayerItem] = [] // reset progress
self.messagesListeningProgress = Float(Self.multiplier * 2)
var AVPlayerItems: [CachingPlayerItem] = []
for url in audioUrls { for url in audioUrls {
let asset = AVAsset(url: url) // if we have a player in the cache, then play it from there
let playerItem = AVPlayerItem(asset: asset) if self.cachedPlayerItemsDict.keys.contains(url.absoluteString), let data = self.cachedPlayerItemsDict[url.absoluteString] {
// keep the cachedplayer item in tact as the player messes with those items
// notification for when each playeritem is done playing let cachedPlayerItem = CachingPlayerItem(data: data, mimeType: "audio/mp4", fileExtension: "m4a")
// NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem) AVPlayerItems.append(cachedPlayerItem)
print("playing a message from cache")
AVPlayerItems.append(playerItem) } else {
let asset = AVAsset(url: url)
let playerItem = CachingPlayerItem(url: url)
AVPlayerItems.append(playerItem)
}
} }
if AVPlayerItems.count <= 0 { if AVPlayerItems.count <= 0 {
@@ -271,6 +280,8 @@ extension InnerCircleViewModel {
return return
} }
print("current state of cached audio files: \(self.cachedPlayerItemsDict)")
// start playing if there are messages to listen to // start playing if there are messages to listen to
print("have \(AVPlayerItems.count) messages to play") print("have \(AVPlayerItems.count) messages to play")
@@ -284,9 +295,6 @@ extension InnerCircleViewModel {
print("player queued up items!!!") print("player queued up items!!!")
// reset progress
self.messagesListeningProgress = Float(Self.multiplier * 2)
DispatchQueue.global(qos: .background).async { DispatchQueue.global(qos: .background).async {
self.addBoundaryTimeObserver(playerItems: AVPlayerItems) self.addBoundaryTimeObserver(playerItems: AVPlayerItems)
} }
@@ -357,14 +365,46 @@ extension InnerCircleViewModel {
// self.timeObserverToken = nil // self.timeObserverToken = nil
// } // }
// } // }
func cacheIncomingMessages(friendMessagesDict: [String: [Message]]) {
// need way of making this get called whenever there are messages that come in but do all this in the background...onreceive of new messages, check if we already have it cached, and if not, then download
guard let userId = AuthSessionStore.getCurrentUserId() else {return}
DispatchQueue.global(qos: .background).async {
// get all relevant messages that the user may listen to
// don't want to cache all messages
for friendId in friendMessagesDict.keys {
let messagesRelatedToFriend = friendMessagesDict[friendId] ?? []
if messagesRelatedToFriend.count == 0 {
return
}
for message in messagesRelatedToFriend {
// if it's starting to get to my messages then don't play
if message.senderId == userId {
break
}
// only add to queue if we can convert the database url to a valid url here
if let audioUrl = URL(string: message.audioDataUrl) { // check if it's a valid url
if !self.cachedPlayerItemsDict.keys.contains(message.audioDataUrl) {
// save to play from mem later
let task = URLSession.shared.dataTask(with: audioUrl) {[weak self] (data, response, error) in
guard let data = data else { return }
print(data)
self?.cachedPlayerItemsDict[audioUrl.absoluteString] = data as? Data
}
task.resume()
}
}
}
}
}
// TODO: need way of deleting cache when we close app or something...can rile up the cost
}
} }
extension InnerCircleViewModel {
// @objc func playerDidFinishPlaying(sender: Notification) {
// // Your code here
// print("finished playing an item")
//
// self.numberofMessagesToPlay -= 1
// }
}