iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
自我挑戰組

來寫看看app好了! Swift探索之旅系列 第 27

Day#27 上傳照片

前言

昨天因為對話的部分有bug...解不粗乃
嗚嗚嗚想說那來先看看別的部分好了(?)

download library

一樣,我們從firebase原先開好的專案進入storage,確認可以被連線後,在本地podfile把library load進來。

podfile

pod 'Firebase/Storage'

接著在終端機執行下載

pod install

上傳

原理

基本上,上傳檔案/照片不外乎就是在上傳的時候將檔案轉換成byte形式上傳,然後儲存在firebase storage空間中,當然,以各檔案類型、原本的形式。

如果使用第三方的登入,那麼做法就會被拆解成:先下載第三方的頭像 -> 上傳該圖片 -> 顯示。
不過這次註冊登入沒有接第三方的api,所以就先這樣~XD

資料結構

我們希望檔案儲存的結構如下,其中加上路徑(子資料夾)images使得標的更清晰。
/images/a8udej-gmail-com_profile_picture.jpg

StorageManager

接著在resource的部分開新檔案,我們使用一般的swift檔案即可,就命名為StorageManager,顧名思義負責與儲存空間相關的邏輯處理。

import FirebaseStorage

跟Database一樣,我們使用static只讓連線使用同一個

final class StorageManager {
    
    static let shared = StorageManager()
    
    private let storage = Storage.storage().reference()
    

然後我們開始開發uploadProfilePicture,其中completion我們希望可以用一個result去把回傳的url包起來,因此可以另外寫一個typealias

    // result is String either Error
    public typealias UploadPictureCompletion = (Result<String, Error>) -> Void
    

在這個方法中有兩個error預期被handle,一個是當無法將圖片正常上傳、第二個是url沒辦法正確的回傳。如果這兩個沒發生,預期是正常的結果,completion完成!

    /// Upload picture to firebase storage and return completion with url string to download
    public func uploadProfilePicture(with data: Data, fileName: String, completion: @escaping UploadPictureCompletion) {
        storage.child("imagess/\(fileName)").putData(data, metadata: nil, completion: {
            metadata, error in
            guard error == nil else {
                print("failed to upload data to firebase for pictures")
                completion(.failure(StorageErrors.failedToUpload))
                return
            }
            
            let reference = self.storage.child("imagess/\(fileName)").downloadURL(completion: { url, error in
                guard let url = url else {
                    print("")
                    completion(.failure(StorageErrors.failedToGetDownloadUrl))
                    return
                }
                
                let urlString = url.absoluteString
                print("download url returned: \(urlString)")
                completion(.success(urlString))
            })
        })
    }

其中,我們也把error訊息分別以enum的方式specify出來。

    public enum StorageErrors : Error {
        case failedToUpload
        case failedToGetDownloadUrl
    }
}

結語

那今天就先到這邊~

若上述內容有誤或可以改進的部分,歡迎留言以及提出任何指教~
謝謝 ヘ| ´ω` |ノ


上一篇
Day#26 傳送對話(1)
下一篇
Day#28 上傳照片(2)+Debug
系列文
來寫看看app好了! Swift探索之旅30

尚未有邦友留言

立即登入留言