Skip to content

Commit

Permalink
Store video and image in storage
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-nirali-s committed Jan 2, 2025
1 parent 3920a20 commit 7919351
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 19 deletions.
8 changes: 8 additions & 0 deletions Data/Data/DI/AppAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public class AppAssembly: Assembly {
TransactionStore.init()
}.inObjectScope(.container)

container.register(FeedbackStore.self) { _ in
FeedbackStore.init()
}.inObjectScope(.container)

// MARK: - Repositories

container.register(UserRepository.self) { _ in
Expand All @@ -87,6 +91,10 @@ public class AppAssembly: Assembly {
TransactionRepository.init()
}.inObjectScope(.container)

container.register(FeedbackRepository.self) { _ in
FeedbackRepository.init()
}.inObjectScope(.container)

container.register(DeepLinkManager.self) { _ in
DeepLinkManager()
}.inObjectScope(.container)
Expand Down
38 changes: 29 additions & 9 deletions Data/Data/Helper/Firebase/StorageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class StorageManager: ObservableObject {
case group
case expense
case payment
case feedback

var pathName: String {
switch self {
Expand All @@ -25,28 +26,47 @@ public class StorageManager: ObservableObject {
"expense_images"
case .payment:
"payment_images"
case .feedback:
"feedback_attachments"
}
}
}

public enum AttachmentType {
case image
case video
case other

var contentType: String {
switch self {
case .image:
return "image/jpg"
case .video:
return "video/mp4"
case .other:
return "application/octet-stream"
}
}
}

private let storage = Storage.storage()

public func uploadImage(for storeType: ImageStoreType, id: String, imageData: Data) async throws -> String? {
public func uploadAttachment(for storeType: ImageStoreType, id: String, attachmentData: Data, attachmentType: AttachmentType = .image) async throws -> String? {
let storageRef = storage.reference(withPath: "/\(storeType.pathName)/\(id)")

let metadata = StorageMetadata()
metadata.contentType = "image/jpg"
metadata.contentType = attachmentType.contentType

do {
// Upload the image data asynchronously
_ = try await storageRef.putDataAsync(imageData, metadata: metadata)
// Upload the attachment data asynchronously
_ = try await storageRef.putDataAsync(attachmentData, metadata: metadata)

// Retrieve the download URL asynchronously
let imageUrl = try await storageRef.downloadURL().absoluteString
LogD("StorageManager: \(#function) Image successfully uploaded to Firebase.")
return imageUrl
let attachmentUrl = try await storageRef.downloadURL().absoluteString
LogD("StorageManager: \(#function) Attachment successfully uploaded to Firebase.")
return attachmentUrl
} catch {
LogE("StorageManager: \(#function) Failed to upload image: \(error).")
LogE("StorageManager: \(#function) Failed to upload attachment: \(error).")
throw error
}
}
Expand All @@ -55,7 +75,7 @@ public class StorageManager: ObservableObject {
try await deleteImage(imageUrl: url)

// Upload the new image asynchronously
return try await uploadImage(for: type, id: id, imageData: imageData)
return try await uploadAttachment(for: type, id: id, attachmentData: imageData)
}

public func deleteImage(imageUrl: String) async throws {
Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Repository/ExpenseRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class ExpenseRepository: ObservableObject {

private func uploadImage(imageData: Data, expense: Expense) async throws -> String {
guard let expenseId = expense.id else { return "" }
return try await storageManager.uploadImage(for: .expense, id: expenseId, imageData: imageData) ?? ""
return try await storageManager.uploadAttachment(for: .expense, id: expenseId, attachmentData: imageData) ?? ""
}

private func hasExpenseChanged(_ expense: Expense, oldExpense: Expense) -> Bool {
Expand Down
6 changes: 6 additions & 0 deletions Data/Data/Repository/FeedbackRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@
//

import Foundation
import UIKit

public class FeedbackRepository: ObservableObject {

@Inject private var store: FeedbackStore
@Inject private var storageManager: StorageManager

public func addFeedback(feedback: Feedback) async throws {
try await store.addFeedback(feedback: feedback)
}

public func uploadAttachment(attachmentId: String, attachmentData: Data, attachmentType: StorageManager.AttachmentType) async throws -> String? {
return try await storageManager.uploadAttachment(for: .feedback, id: attachmentId, attachmentData: attachmentData, attachmentType: attachmentType)
}
}
2 changes: 1 addition & 1 deletion Data/Data/Repository/GroupRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class GroupRepository: ObservableObject {
guard let groupId = group.id else { return "" }

// Upload the image and get the image URL
return try await storageManager.uploadImage(for: .group, id: groupId, imageData: imageData) ?? ""
return try await storageManager.uploadAttachment(for: .group, id: groupId, attachmentData: imageData) ?? ""
}

public func addMemberToGroup(groupId: String, memberId: String) async throws {
Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Repository/TransactionRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class TransactionRepository: ObservableObject {

private func uploadImage(imageData: Data, transaction: Transactions) async throws -> String {
guard let transactionId = transaction.id else { return "" }
return try await storageManager.uploadImage(for: .payment, id: transactionId, imageData: imageData) ?? ""
return try await storageManager.uploadAttachment(for: .payment, id: transactionId, attachmentData: imageData) ?? ""
}

private func hasTransactionChanged(_ transaction: Transactions, oldTransaction: Transactions) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion Data/Data/Repository/UserRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class UserRepository: ObservableObject {
}

private func uploadImage(imageData: Data, user: AppUser) async throws -> AppUser {
let imageURL = try await storageManager.uploadImage(for: .user, id: user.id, imageData: imageData)
let imageURL = try await storageManager.uploadAttachment(for: .user, id: user.id, attachmentData: imageData)
var newUser = user
newUser.imageUrl = imageURL
return try await updateUser(user: newUser)
Expand Down
27 changes: 21 additions & 6 deletions Splito/UI/Home/Account/Feedback/FeedbackViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ extension FeedbackViewModel {
self?.showAlert = false
self?.router.pop()
}))
LogD("ActivityLogViewModel: \(#function) Activity logs fetched successfully.")
LogD("FeedbackViewModel: \(#function) Feedback submitted successfully.")
} catch {
self?.showLoader = false
self?.showToastForError()
LogE("ActivityLogViewModel: \(#function) Failed to fetch activity logs: \(error).")
LogE("FeedbackViewModel: \(#function) Failed to submit feedback: \(error).")
}
}
}
Expand Down Expand Up @@ -151,22 +151,37 @@ extension FeedbackViewModel {

if let imageData = attachment.image?.jpegRepresentationData {
let attachmentData = AttachmentData(data: imageData, attachment: attachment)
upload(attachmentData: attachmentData)
upload(attachmentData: attachmentData, attachmentType: .image)
} else if let data = attachment.videoData {
if data.count <= VIDEO_SIZE_LIMIT_IN_BYTES {
let attachmentData = AttachmentData(data: data, attachment: attachment)
upload(attachmentData: attachmentData)
upload(attachmentData: attachmentData, attachmentType: .video)
} else {
selectedAttachments.removeAll { $0.id == attachment.id }
showToastFor(toast: ToastPrompt(type: .error, title: "Error", message: "The video size exceeds the maximum allowed limit. Please select a smaller video."))
}
}
}

func upload(attachmentData: AttachmentData) {
public func upload(attachmentData: AttachmentData, attachmentType: StorageManager.AttachmentType) {
uploadingAttachments.append(attachmentData.attachment)

// Need to upload
Task {
do {
let attachmentId = attachmentData.attachment.id
let attachmentUrl = try await feedbackRepository.uploadAttachment(attachmentId: attachmentId, attachmentData: attachmentData.data, attachmentType: attachmentType)

// Update attachment URLs with the uploaded URL
if let attachmentUrl {
self.attachmentsUrls.append(AttachmentInfo(id: attachmentId, url: attachmentUrl))
self.uploadingAttachments.removeAll { $0.id == attachmentId }
}
} catch {
self.failedAttachments.append(attachmentData.attachment)
self.uploadingAttachments.removeAll { $0.id == attachmentData.attachment.id }
LogE("FeedbackViewModel: \(#function) Failed to upload attachment: \(error)")
}
}
}
}

Expand Down

0 comments on commit 7919351

Please sign in to comment.