Advertisement
  1. Code
  2. Firebase

Bắt đầu với Firebase Storage cho iOS

Scroll to top
Read Time: 15 min

() translation by (you can also view the original English article)

Giới thiệu

Ngoài việc cho phép các nhà phát triển iOS dễ dàng lưu trữ dữ liệu trên cloud, cũng như xác thực người dùng thông qua SDK mạnh mẽ của họ, Firebase cũng cung cấp giải pháp lưu trữ thuận tiện cho media. Firebase Storage cho phép các nhà phát triển lưu trữ và truy xuất các file âm thanh, hình ảnh và video trên cloud. Đó là, Firebase Storage trình bày một nhóm SDK để mang đến cho các nhà phát triển khả năng quản lý asset do người dùng tạo ra cùng với sản phẩm anh chị em của nó, Database thời gian thực Firebase, lưu trữ nội dung text của người dùng.

Tuy nhiên, Firebase Storage không chỉ là container cho các asset cho media. Nó hỗ trợ các nhà phát triển bằng cách cung cấp đồng bộ hóa offline cho người dùng và thiết bị của họ, xếp hàng và hồi phục hình ảnh và các video khi người dùng tắt và trở lại online. Điều này hiệu quả tương tự như cách Firebase Realtime Database phối hợp đồng bộ hóa dữ liệu người dùng với back-end.

Firebase Storage logoFirebase Storage logoFirebase Storage logo

Hướng dẫn này tiếp tục từ hướng dẫn trước đây của chúng tôi Getting Started With Firebase Authentication for iOS, ở đó chúng tôi đã xem xét cách quản lý, lưu trữ và làm việc với người dùng trong Firebase.

Mục tiêu của bài hướng dẫn này

Hướng dẫn này sẽ đưa bạn đến SDK của Firebase Storage, để giúp bạn quản lý các tài nguyên media cho ứng dụng của mình - như hình ảnh, âm thanh, và các video- việc lưu trữ chúng từ xa trên cloud và truy xuất chúng trong ứng dụng của bạn. Trong hướng dẫn này, bạn sẽ học cách:

  • thiết lập ứng dụng của bạn cho Firebase Storage
  • tạo ra và làm việc với các tài liệu tham khảo lưu trữ
  • tải media lên Firebase Storage
  • tải về media từ Firebase Storage

Kiến thức cần có

Hướng dẫn này giả định rằng bạn đã từng tiếp xúc với Firebase và nền tảng phát triển Swift và Xcode. Điều quan trọng nữa là bạn đã làm qua hướng dẫn Getting Started With Firebase Authentication for iOS của chúng tôi trước tiên vì bạn sẽ cần xác thực người dùng của mình trước khi truy xuất nhiều chức năng của Firebase Storage, bao gồm cả đường dẫn cho asset.

Firebase Storage là gì?

Là nhà phát triển, bạn có thể sử dụng Firebase Realtime Database để truy cập và tương tác với Firebase Storage bucket mà không có máy chủ mà không cần phải tạo ra và lưu trữ máy chủ của riêng bạn. Firebase Storage tận dụng bộ nhớ đệm cục bộ trên thiết bị để lưu trữ asset khi offline và cung cấp asset khi người dùng online trở lại, với dữ liệu cục bộ được tự động đồng bộ hóa.

Các nhà phát triển không còn phải đối mặt với sự phức tạp của việc đồng bộ hóa dữ liệu và nội dung thông qua các thư viện kết nối tiêu chuẩn iOS của Apple và phải xử lý nhiều tình huống có thể gây gián đoạn việc chuyển giao.

Trên thực tế, các sản phẩm của Firebase nhận ra rằng người dùng di động trong thế giới thực phải đối mặt với khả năng các tình huống gián đoạn tín hiệu hoặc tín hiệu kém. Việc có thể đồng bộ hóa dữ liệu trên thiết bị để chuyển đổi sau này giúp trải nghiệm người dùng tốt hơn nhiều, đồng thời giảm bớt nhiều công việc cho nhà phát triển.

Bảo mật cũng là tối quan trọng với Firebase Storage, như với phần còn lại của bộ sản phẩm Firebase. Điều này có nghĩa là nhà phát triển có thể hạn chế quyền truy cập vào các mục lưu trữ bằng cách xác thực người dùng bằng Xác thực Firebase, được xây dựng dựa trên mô hình bảo mật bắt buộc cho phép kiểm soát quyền truy cập vào đường dẫn, file và metadata trên cơ sở theo vai trò.

Cuối cùng, các ứng dụng được lưu trữ trên Firebase Storage được hưởng lợi từ cơ sở hạ tầng của Google để mở rộng khi nền tảng người dùng phát triển. Chúng ta sẽ khám phá một số khái niệm này sau trong hướng dẫn, nhưng để bắt đầu, hãy để xem qua thiết lập ứng dụng của bạn để hoạt động với Firebase. Sau đó, chúng ta sẽ xem các pointer tham chiếu của Storage Reference.

Thiết lập dự án

Nếu bạn từng làm việc với Firebase trước đây, thì bạn sẽ cảm thấy quen thuộc. Nếu không, bạn sẽ cần tạo một tài khoản trong Firebase và làm theo các hướng dẫn trong phần Set Up the Project (thiết lập dự án) của bài viết Get Started With Firebase Authentication for iOS.

Bạn có thể tải xuống mã nguồn hoàn chỉnh cho dự án này bằng cách nhập thông tin sau vào terminal:

1
$ git clone git@github.com:tutsplus/get-started-with-firebase-storage-for-ios.git

Để lưu trữ, chúng tôi sẽ cần thêm Firebase/Storage vào Podfile của chúng tôi, như hiển thị bên dưới:

1
pod 'Firebase/Core'
2
pod 'Firebase/Storage'

Lưu lại và sau đó nhập thông tin sau vào terminal của bạn để xây dựng các nhóm:

1
pod install

Trong AppDelegate phương thức application:didFinishLaunchingWithOptions:, dòng sau đây hiện diện:

1
FirebaseApp.configure()

Đảm bảo bạn cũng đã định cấu hình dự án của mình thông qua Firebase Console một cách chính xác, như được mô tả trong phần Set Up the Project của hướng dẫn Get Started With Firebase Authentication for iOS.

Khi môi trường của bạn đã sẵn sàng, chúng ta có thể chuyển sang xem các tham chiếu lưu trữ, bắt đầu với cách tạo reference pointer.

Tạo mới và làm việc với tài liệu tham khảo lưu trữ

Sử dụng Firebase Storage, bạn có thể tương tác với cloud bucket của riêng bạn, đại diện cho một filesystem của hình ảnh và video được lưu trữ của bạn. Bạn sử dụng tham chiếu lưu trữ cho một đường dẫn hoặc file cụ thể trong một đường dẫn, trong filesystem mà sau đó bạn cấp quyền truy cập cho ứng dụng của mình để có thể tương tác với nó bằng cách truyền dữ liệu.

Có một pointer hướng tới một đường dẫn hoặc file trong đường dẫn cho phép bạn upload, download, cập nhật hoặc xóa đường dẫn đó. Để tạo một tham chiếu, bạn chỉ cần tạo một instance của Storage.storage(), như sau:

1
let store = Storage.storage()
2
let storeRef = store.reference()

Bây giờ bạn có một tham chiếu đến thư mục gốc của filesystem và bạn có thể xét cấu trúc cho bucket của mình theo ý muốn, ví dụ bằng cách tạo ra một cấu trúc thư mục.

Để truy cập các file và đường dẫn trong bucket của bạn, hãy gọi phương thức child(), như sau:

1
let userProfilesRef = storeRef.child("images/profiles")
2
...
3
let logoRef = storeRef.child("images/logo.png")

Các tham chiếu là viết tắt cho đường dẫn Firebase hoàn chỉnh đến file của bạn thông qua nhóm của bạn, thay vì nhập toàn bộ đường dẫn URL của Firebase bucket. Bên cạnh phương thức child(), bạn cũng có thể điều hướng phân cấp của mình bằng cách sử dụng các phương thức root() và parent() và bạn có thể chain (xâu chuỗi) các phương thức này, như bên dưới:

1
let userProfilesRef = logoRef.parent()?.child("profiles")

Như bạn thấy, chúng tôi sẽ nhận được kết quả tương tự cho userProfilesRef khi chúng tôi đã có trong code trước đó. Điều tuyệt vời về tham chiếu là chúng cực kỳ gọn nhẹ, vậy bạn có thể có nhiều tham chiếu trong ví dụ giá trị ứng dụng của mình như bạn muốn mà không ảnh hưởng đến hiệu suất của ứng dụng.

Bây giờ bạn đã hiểu các khía cạnh cơ bản khi làm việc với các tài liệu tham khảo Firebase Storage, hãy chuyển phần upload và download các file từ bucket của bạn.

Upload media lên Firebase Storage

Cách đơn giản nhất để upload một file để chuyển một đại diện NSData về nội dung của nó trong bộ nhớ:

1
let uploadUserProfileTask = userProfilesRef.child("\(userID).png").putData(data, metadata: nil) { (metadata, error) in
2
  guard let metadata = metadata else {
3
    print("Error occurred: \(error)")
4
    return
5
  }
6
    print("download url for profile is \(metadata.downloadURL)")
7
}

Bạn có thể quản lý quá các upload của mình bằng cách kiểm soát thời điểm bắt đầu, tạm dừng, tiếp tục và hủy tải lên. Bạn cũng có thể lắng nghe các sự kiện tiếp theo được kích hoạt, đó là:

  • pause - tạm ngừng
  • resume - tiếp tục
  • cancel - hủy bỏ

Tham khảo uploadUserProfileTask chúng tôi đã sử dụng trước đó, bạn có thể kiểm soát phần upload của mình bằng các phương pháp sau:

1
uploadUserProfileTask.pause()
2
uploadUserProfileTask.resume()
3
uploadUserProfileTask.cancel()

Bạn cũng có thể theo dõi một quá trình chuyển đang diễn ra bằng cách chỉ cần đặt một observer vào đối tượng tác vụ:

1
let progressObserver = uploadUserProfileTask.observe(.progress) { snapshot in
2
  let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
3
    / Double(snapshot.progress!.totalUnitCount)
4
    print(percentComplete)
5
}

Hãy để xem cách bạn tiếp cận phần download hình ảnh hoặc video từ bucket.

Download media từ Firebase Storage

Để có thể download và trình diễn hình ảnh của bạn, hãy bắt đầu như bạn đã làm với việc upload và khai báo một pointer tham chiếu đến đường dẫn đã định của bạn. Sau đó bắt đầu download bằng cách sử dụng hàm closure dataWithMaxSize:completion::

1
logoRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
2
  if let error = error {
3
    print("Error \(error)")
4
  } else {
5
    let logoImage = UIImage(data: data!)
6
  }
7
}

Nếu bạn tận dụng FirebaseUI, thì bạn có thể chỉ cần FirebaseUI quản lý việc tải về, lưu bộ nhớ đệm và hiển thị hình ảnh cho bạn theo cách đơn giản hơn:

1
...
2
self.imageView.sd_setImage(with: logoRef, placeholderImage: placeholderImage) 

Để biết thông tin về việc triển khai FirebaseUI, hãy tham khảo tài liệu về FirebaseUI.

Quản lý phần download hoạt động theo cách tương tự như quản lý và kiểm soát phần upload. Đây là một ví dụ:

1
let downloadTask = storageRef.child("images/logo.jpg").write(toFile: localFile)
2
3
// Pause the download
4
downloadTask.pause()
5
6
// Resume the download
7
downloadTask.resume()
8
9
// Cancel the download
10
downloadTask.cancel()

Bạn cũng có thể chỉ định observer như chúng tôi đã làm để upload, để theo dõi tiến trình chuyển download trong thời gian thực:

1
let progressObserverDownload = downloadTask.observe(.progress) { snapshot in
2
  let percentComplete = 100.0 * Double(snapshot.progress!.completedUnitCount)
3
    / Double(snapshot.progress!.totalUnitCount)
4
    print(percentComplete)
5
}

Được trang bị tổng quan về cách làm việc với các tham chiếu và cách để upload và download các asset từ bucket của bạn, giờ bạn đã sẵn sàng xem cách triển khai Firebase Storage cho dự án mẫu của chúng tôi: FirebaseDo.

Dự án mẫu FirebaseDo

Bây giờ, bạn nên copy ứng dụng FirebaseDo, vì vậy hãy tiếp tục xây dựng và chạy dự án. Bạn sẽ thấy rằng tất cả điều ứng dụng làm là xác thực người dùng qua thoại hoặc email:

App screen with sign in options by phone or emailApp screen with sign in options by phone or emailApp screen with sign in options by phone or email

Mục tiêu của chúng tôi là cải thiện dần dần chức năng của ứng dụng, để một khi người dùng xác thực thành công, họ sẽ có thể upload ảnh hồ sơ. Hầu hết các công việc của chúng tôi sẽ trong HomeViewControll và Associated Storyboard của nó. Trước tiên, hãy để đến file HomeViewControll.

HomeViewController

Trước khi chúng ta xem các phương thức của controller này, chúng ta sẽ cần thêm giao thức UIImagePickerControllerDelegate vào class của chúng ta để chúng ta có thể làm việc với các phương thức ủy nhiệm của nó. Chúng tôi cũng sẽ cần thêm một ví dụ về đối tượng picker để người dùng của chúng tôi có thể chọn ảnh từ thư viện của họ.

1
class HomeViewController: UIViewController, FUIAuthDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate  {
2
    
3
    @IBOutlet weak var myImageView: UIImageView!
4
    let picker = UIImagePickerController()
5
6
    ...
7
    fileprivate(set) var auth:Auth?
8
    fileprivate(set) var authUI: FUIAuth? //only set internally but get externally
9
    fileprivate(set) var authStateListenerHandle: AuthStateDidChangeListenerHandle?

Bổ sung phần sau vào cuối phương thức viewDidLoad():

1
self.picker.delegate = self
2
self.refreshProfileImage()

Chúng tôi sẽ triển khai phương thức refreshProfileImage(), sẽ được gọi để tải xuống hình ảnh mà chúng tôi đã hiển thị trong ViewController của chúng tôi. Trước tiên, chúng tôi sẽ xác nhận rằng người dùng thực sự đã được xác thực trước khi tạo một tham chiếu sẽ truy xuất hình ảnh hồ sơ người dùng từ đường dẫn /images/user_id/profile_photo.jpg trong bucket của chúng tôi. Cuối cùng, chúng tôi sẽ cập nhật view hình ảnh của chúng tôi với ảnh lấy được.

1
func refreshProfileImage(){
2
        if let user = Auth.auth().currentUser{
3
            let store = Storage.storage()
4
            let storeRef = store.reference().child("images/\(user.uid)/profile_photo.jpg")
5
           
6
            storeRef.getData(maxSize: 1 * 1024 * 1024) { data, error in
7
                if let error = error {
8
                    print("error: \(error.localizedDescription)")
9
                } else {
10
                    let image = UIImage(data: data!)
11
                    self.myImageView.image = image
12
                }
13
            }
14
        }else{
15
            print("You should be logged in")
16
            self.loginAction(sender: self)
17
            return
18
        }
19
20
    }

Tiếp theo, chúng tôi tạo một phương thức @IBAction cho button thư viện ảnh mà chúng tôi sẽ sớm kết nối từ story của mình:

1
@IBAction func libraryAction(_ sender: Any) {
2
        self.picker.allowsEditing = false
3
        self.picker.sourceType = .photoLibrary
4
        self.picker.mediaTypes = UIImagePickerController.availableMediaTypes(for: .photoLibrary)!
5
        self.present(picker, animated: true, completion: {
6
            print("handle saving")
7
        })
8
    }

Cuối cùng, chúng tôi bổ sung hai phương thức ủy nhiệm cho UIImagePickerController của chúng tôi, để xử lý khi người dùng hủy UIImagePicker, cũng như việc xử lý hình ảnh đã chọn:

1
 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
2
     dismiss(animated: true, completion: nil)
3
 }
4
5
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
6
        self.dismiss(animated: true, completion: nil)
7
8
        let profileImageFromPicker = info[UIImagePickerControllerOriginalImage] as! UIImage
9
        
10
        let metadata = StorageMetadata()
11
        metadata.contentType = "image/jpeg"
12
        
13
        let imageData: Data = UIImageJPEGRepresentation(profileImageFromPicker, 0.5)!
14
        
15
        let store = Storage.storage()
16
        let user = Auth.auth().currentUser
17
        if let user = user{
18
            let storeRef = store.reference().child("images/\(user.uid)/profile_photo.jpg")
19
            ASProgressHud.showHUDAddedTo(self.view, animated: true, type: .default)
20
            let _ = storeRef.putData(imageData, metadata: metadata) { (metadata, error) in
21
                ASProgressHud.hideHUDForView(self.view, animated: true)
22
                guard let _ = metadata else {
23
                    print("error occurred: \(error.debugDescription)")
24
                    return
25
                }
26
27
                self.myImageView.image = profileImageFromPicker
28
            }
29
            
30
        }
31
        
32
    }

Khi người dùng chọn một ảnh, chúng tôi loại bỏ picker nhưng giữ lại tham chiếu đến ảnh được chọn. Tiếp theo, chúng tôi tạo một đối tượng StorageMetadata() để chúng tôi có thể cho Firebase biết rằng chúng tôi sẽ upload một file JPEG.

Như chúng ta đã làm trong phương thức refreshProfileImage(), chúng ta sẽ khẳng định rằng người dùng được xác thực và sau đó tạo một tham chiếu đến đường dẫn hình ảnh nơi chúng ta muốn lưu trữ hồ sơ người dùng của chúng ta. Sử dụng phương thức putData(), sau đó chúng tôi không đồng bộ upload hình ảnh của mình lên vị trí bucket được chỉ định, trước khi xét image view của chúng tôi sang hình ảnh mới được chọn.

Trước khi chúng tôi có thể xây dựng và chạy ứng dụng của mình, chúng tôi sẽ cần bổ sung các điều khiển thích hợp vào storyboard của mình:

Storyboard

Trong storyboard chính của chúng tôi, hãy bổ sung image view với placeholder sẽ đại diện cho hồ sơ hiện tại của người dùng, sau đó kéo để liên kết image view vào cái chúng tôi đã khai báo như một @IBOutlet trong class HomeViewController của chúng tôi. Tiếp theo, bổ sung một thanh công cụ với một button mà bạn sẽ sử dụng như một @IBAction để gọi phương thức libraryAction() mà chúng ta đã tạo ra trước đó trong HomeViewController.

Storyboard của bạn bây giờ sẽ giống như sau:

Storyboard view with placeholder profile imageStoryboard view with placeholder profile imageStoryboard view with placeholder profile image

Không có bất kỳ lỗi nào, bạn có thể tiếp tục xây dựng và chạy ứng dụng của mình một lần nữa và xác thực bằng cách tạo người dùng mới hoặc sử dụng nhóm thông tin đăng nhập của người dùng hiện tại.

Sau đó, bạn sẽ được trình bày với HomeViewController, ở đó bạn sẽ chọn nút + để thêm hình ảnh từ thiết bị của mình hoặc thư viện ảnh giả lập. Khi bạn đã chọn một bức ảnh, nó sẽ upload lên bucket của Firebase. Bạn có thể xác nhận rằng nó đã được upload thành công bằng cách đi tới tab Storage của Firebase Console, như hiển thị bên dưới:

The Storage tab of your Firebase ConsoleThe Storage tab of your Firebase ConsoleThe Storage tab of your Firebase Console

Nếu bạn dừng lại và chạy lại ứng dụng trong Xcode, bạn cũng sẽ thấy hình ảnh bạn upload lần cuối xuất hiện lại, xác nhận thêm rằng chúng tôi đã được upload và download thành công bằng Firebase Storage.

Tổng kết

Hướng dẫn này đã trình bày cách dễ dàng để thêm quản lý và lưu trữ tài sản không đồng bộ vào ứng dụng Firebase hiện tại chỉ với một vài dòng mã. Điều này cung cấp cho bạn một cách thuận tiện để quản lý asset của ứng dụng của bạn, đồng thời cho phép bạn xử lý đồng bộ hóa offline gọn gàng và thuận tiện.

Firebase Storage là một lựa chọn tất yếu cho các nhà phát triển iOS đã ở trong hệ sinh thái Firebase. Nó cung cấp cho các nhà phát triển sự bảo mật của một mô hình bảo mật cần thiết được cung cấp bởi Xác thực Firebase, cũng như khả năng được cung cấp bởi Firebase Realtime Database.

Hãy xem một số bài viết khác của chúng tôi về phát triển ứng dụng iOS!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.