1. Ikhtisar
Selamat datang di codelab Obrolan Ramah. Dalam codelab ini, Anda akan mempelajari cara menggunakan platform Firebase untuk membuat aplikasi iOS. Anda akan mengimplementasikan klien chat dan memantau performanya menggunakan Firebase.
Apa yang akan Anda pelajari
- Izinkan pengguna untuk masuk.
- Sinkronkan data menggunakan Firebase Realtime Database.
- Simpan file biner di Firebase Storage.
Apa yang Anda perlukan
- kode X
- KakaoPod
- Perangkat uji dengan iOS 8.0+ atau simulator
Bagaimana Anda akan menggunakan tutorial ini?
Bagaimana menilai pengalaman Anda dalam membuat aplikasi iOS?
2. Dapatkan kode contoh
Kloning repositori GitHub dari baris perintah.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Bangun aplikasi pemula
Untuk membangun aplikasi pemula:
- Di jendela terminal, navigasikan ke
direktori
ios-starter/swift-starter
dari unduhan kode sampel Anda - Jalankan
pod install --repo-update
- Buka file FriendlyChatSwift.xcworkspace untuk membuka proyek di Xcode.
- Klik
Tombol Jalankan .
Anda akan melihat layar beranda Obrolan Ramah muncul setelah beberapa detik. UI akan muncul. Namun, saat ini Anda tidak dapat masuk, mengirim atau menerima pesan. Aplikasi akan dibatalkan dengan pengecualian hingga Anda menyelesaikan langkah berikutnya.
4. Buat Proyek konsol Firebase
Buat proyek
Dari Firebase console pilih Tambahkan Proyek .
Panggil proyek FriendlyChat
, lalu klik Buat Proyek .
Hubungkan aplikasi iOS Anda
- Dari layar Ikhtisar Proyek pada proyek baru Anda, klik Tambahkan Firebase ke aplikasi iOS Anda .
- Masukkan ID paket, sebagai "
com.google.firebase.codelab.FriendlyChatSwift
". - Masukkan id App Store sebagai "
123456
". - Klik Daftarkan Aplikasi .
Tambahkan file GoogleService-Info.plist ke aplikasi Anda
Di layar kedua, klik Download GoogleService-Info.plist untuk mendownload file konfigurasi yang berisi semua metadata Firebase yang diperlukan untuk aplikasi Anda. Salin file itu ke aplikasi Anda dan tambahkan ke target FriendlyChatSwift .
Anda sekarang dapat mengklik "x" di sudut kanan atas popup untuk menutupnya – lewati langkah 3 dan 4 – karena Anda akan melakukan langkah-langkah tersebut di sini.
Impor modul Firebase
Mulailah dengan memastikan modul Firebase
diimpor.
AppDelegate.swift , FCViewController.swift
import Firebase
Konfigurasikan Firebase di AppDelegate
Gunakan metode "konfigurasi" di FirebaseApp di dalam fungsi application:didFinishLaunchingWithOptions untuk mengonfigurasi layanan Firebase yang mendasari dari file .plist Anda.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. Identifikasi Pengguna
Gunakan Aturan Untuk Membatasi Pengguna yang Diautentikasi
Kami sekarang akan menambahkan aturan yang mengharuskan otentikasi sebelum membaca atau menulis pesan apa pun. Untuk melakukan ini kita menambahkan aturan berikut ke objek data pesan kita. Dari dalam bagian Database di Firebase console pilih Realtime Database, lalu klik tab Rules. Kemudian perbarui aturannya sehingga terlihat seperti ini:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
Untuk informasi selengkapnya tentang cara kerjanya (termasuk dokumentasi tentang variabel "auth") lihat dokumentasi keamanan Firebase .
Konfigurasikan API Otentikasi
Sebelum aplikasi Anda dapat mengakses Firebase Authentication API atas nama pengguna, Anda harus mengaktifkannya
- Navigasikan ke Firebase console dan pilih proyek Anda
- Pilih Otentikasi
- Pilih tab Metode Masuk
- Alihkan tombol Google ke diaktifkan (biru)
- Tekan Simpan pada dialog yang dihasilkan
Jika nanti Anda mendapatkan error dalam codelab ini dengan pesan "CONFIGURATION_NOT_FOUND", kembali ke langkah ini dan periksa kembali pekerjaan Anda.
Konfirmasikan ketergantungan Firebase Auth
Konfirmasikan bahwa dependensi Firebase Auth ada di file Podfile
.
File Pod
pod 'Firebase/Auth'
Siapkan Info.plist Anda untuk Masuk dengan Google.
Anda harus menambahkan skema URL khusus ke proyek XCode Anda.
- Buka konfigurasi proyek Anda: klik dua kali nama proyek di tampilan pohon sebelah kiri. Pilih aplikasi Anda dari bagian TARGET, lalu pilih tab Info, dan perluas bagian Jenis URL.
- Klik tombol +, dan tambahkan skema URL untuk ID klien terbalik Anda. Untuk menemukan nilai ini, buka file konfigurasi GoogleService-Info.plist, dan cari kunci REVERSED_CLIENT_ID. Salin nilai kunci tersebut, dan tempelkan ke dalam kotak Skema URL di halaman konfigurasi. Biarkan kolom lainnya kosong.
- Ketika selesai, konfigurasi Anda akan terlihat seperti berikut (tetapi dengan nilai khusus aplikasi Anda):
Tetapkan clientID untuk Masuk dengan Google
Setelah Firebase dikonfigurasi, kita dapat menggunakan clientID untuk menyiapkan Login dengan Google di dalam metode "didFinishLaunchingWithOptions:".
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}
Tambahkan pengendali masuk
Setelah hasil Google Sign-In berhasil, gunakan akun tersebut untuk mengautentikasi dengan Firebase.
AppDelegate.swift
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
if let error = error {
print("Error \(error)")
return
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print("Error \(error)")
return
}
}
}
Pengguna masuk secara otomatis. Kemudian tambahkan pendengar ke Firebase Auth, untuk mengizinkan pengguna masuk ke aplikasi, setelah berhasil masuk. Dan hapus pendengar di deinit.
SignInViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self
GIDSignIn.sharedInstance().signInSilently()
handle = Auth.auth().addStateDidChangeListener() { (auth, user) in
if user != nil {
MeasurementHelper.sendLoginEvent()
self.performSegue(withIdentifier: Constants.Segues.SignInToFp, sender: nil)
}
}
}
deinit {
if let handle = handle {
Auth.auth().removeStateDidChangeListener(handle)
}
}
Keluar
Tambahkan metode Keluar
FCViewController.swift
@IBAction func signOut(_ sender: UIButton) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
dismiss(animated: true, completion: nil)
} catch let signOutError as NSError {
print ("Error signing out: \(signOutError.localizedDescription)")
}
}
Uji Membaca Pesan sebagai Pengguna yang Masuk
- Klik
Tombol Jalankan .
- Anda akan segera diarahkan ke layar masuk. Ketuk tombol Masuk dengan Google.
- Anda kemudian akan diarahkan ke layar pesan jika semuanya berfungsi dengan baik.
6. Aktifkan Basis Data Waktu Nyata
Impor Pesan
Dalam proyek Anda di Firebase console, pilih item Database di bilah navigasi kiri. Di menu luapan Database pilih Impor JSON . Telusuri file initial_messages.json
di direktori Friendlychat, pilih lalu klik tombol Impor . Ini akan menggantikan data apa pun yang saat ini ada di database Anda. Anda juga dapat mengedit database secara langsung, menggunakan tanda x hijau + dan merah untuk menambah dan menghapus item.
Setelah mengimpor database Anda akan terlihat seperti ini:
Konfirmasikan Ketergantungan Database Firebase
Di blok dependensi file Podfile
, konfirmasikan bahwa Firebase/Database
disertakan.
File Pod
pod 'Firebase/Database'
Sinkronkan Pesan yang Ada
Tambahkan kode yang menyinkronkan pesan yang baru ditambahkan ke UI aplikasi.
Kode yang Anda tambahkan di bagian ini akan:
- Inisialisasi database Firebase dan tambahkan pendengar untuk menangani perubahan yang dilakukan pada database.
- Perbarui
DataSnapshot
sehingga pesan baru akan ditampilkan.
Ubah metode "deinit", "configureDatabase", dan "tableView:cellForRow indexPath:" FCViewController Anda; ganti dengan kode yang ditentukan di bawah ini:
FCViewController.swift
deinit {
if let refHandle = _refHandle {
self.ref.child("messages").removeObserver(withHandle: _refHandle)
}
}
func configureDatabase() {
ref = Database.database().reference()
// Listen for new messages in the Firebase database
_refHandle = self.ref.child("messages").observe(.childAdded, with: { [weak self] (snapshot) -> Void in
guard let strongSelf = self else { return }
strongSelf.messages.append(snapshot)
strongSelf.clientTable.insertRows(at: [IndexPath(row: strongSelf.messages.count-1, section: 0)], with: .automatic)
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
let cell = self.clientTable.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
// Unpack message from Firebase DataSnapshot
let messageSnapshot = self.messages[indexPath.row]
guard let message = messageSnapshot.value as? [String: String] else { return cell }
let name = message[Constants.MessageFields.name] ?? ""
let text = message[Constants.MessageFields.text] ?? ""
cell.textLabel?.text = name + ": " + text
cell.imageView?.image = UIImage(named: "ic_account_circle")
if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage(data: data)
}
return cell
}
Uji Sinkronisasi Pesan
- Klik
Tombol Jalankan .
- Klik tombol Masuk untuk memulai untuk membuka jendela pesan.
- Tambahkan pesan baru langsung di Firebase console dengan mengklik simbol + hijau di sebelah entri "pesan" dan menambahkan objek seperti berikut:
- Konfirmasikan bahwa mereka muncul di UI Obrolan Ramah.
7. Kirim Pesan
Terapkan Kirim Pesan
Dorong nilai ke database. Saat Anda menggunakan metode push untuk menambahkan data ke Firebase Realtime Database, ID otomatis akan ditambahkan. ID yang dibuat secara otomatis ini bersifat berurutan, yang memastikan bahwa pesan baru akan ditambahkan dalam urutan yang benar.
Ubah metode "sendMessage:" FCViewController Anda; ganti dengan kode yang ditentukan di bawah ini:
FCViewController.swift
func sendMessage(withData data: [String: String]) {
var mdata = data
mdata[Constants.MessageFields.name] = Auth.auth().currentUser?.displayName
if let photoURL = Auth.auth().currentUser?.photoURL {
mdata[Constants.MessageFields.photoURL] = photoURL.absoluteString
}
// Push data to Firebase Database
self.ref.child("messages").childByAutoId().setValue(mdata)
}
Tes Mengirim Pesan
- Klik
Tombol Jalankan .
- Klik Masuk untuk membuka jendela pesan.
- Ketik pesan dan tekan kirim. Pesan baru akan terlihat di UI aplikasi dan di Firebase console.
8. Simpan dan Terima gambar
Konfirmasikan Ketergantungan Penyimpanan Firebase
Di blok dependensi Podfile
, konfirmasikan bahwa Firebase/Storage
disertakan.
File Pod
pod 'Firebase/Storage'
Aktifkan Firebase Storage di dasbor
Buka Firebase console dan konfirmasikan bahwa Penyimpanan diaktifkan dengan domain "gs://PROJECTID.appspot.com".
Jika Anda melihat jendela aktivasi, klik "MULAI" untuk mengaktifkannya dengan aturan default.
Konfigurasikan FirebaseStorage
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
Terima gambar dalam pesan yang ada
Tambahkan kode yang mendownload gambar dari Firebase Storage.
Ubah metode "tableView: cellForRowAt indexPath:" FCViewController Anda; ganti dengan kode yang ditentukan di bawah ini:
FCViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
let cell = self.clientTable .dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
// Unpack message from Firebase DataSnapshot
let messageSnapshot: DataSnapshot! = self.messages[indexPath.row]
guard let message = messageSnapshot.value as? [String:String] else { return cell }
let name = message[Constants.MessageFields.name] ?? ""
if let imageURL = message[Constants.MessageFields.imageURL] {
if imageURL.hasPrefix("gs://") {
Storage.storage().reference(forURL: imageURL).getData(maxSize: INT64_MAX) {(data, error) in
if let error = error {
print("Error downloading: \(error)")
return
}
DispatchQueue.main.async {
cell.imageView?.image = UIImage.init(data: data!)
cell.setNeedsLayout()
}
}
} else if let URL = URL(string: imageURL), let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage.init(data: data)
}
cell.textLabel?.text = "sent by: \(name)"
} else {
let text = message[Constants.MessageFields.text] ?? ""
cell.textLabel?.text = name + ": " + text
cell.imageView?.image = UIImage(named: "ic_account_circle")
if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage(data: data)
}
}
return cell
}
9. Kirim Pesan Gambar
Terapkan Simpan dan Kirim Gambar
Unggah gambar dari pengguna, lalu sinkronkan URL penyimpanan gambar ini ke database sehingga gambar ini dikirim ke dalam pesan.
Ubah metode "imagePickerController: didFinishPickingMediaWithInfo:" FCViewController Anda; ganti dengan kode yang ditentukan di bawah ini:
FCViewController.swift
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any]) {
picker.dismiss(animated: true, completion:nil)
guard let uid = Auth.auth().currentUser?.uid else { return }
// if it's a photo from the library, not an image from the camera
if #available(iOS 8.0, *), let referenceURL = info[UIImagePickerControllerReferenceURL] as? URL {
let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
let asset = assets.firstObject
asset?.requestContentEditingInput(with: nil, completionHandler: { [weak self] (contentEditingInput, info) in
let imageFile = contentEditingInput?.fullSizeImageURL
let filePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\((referenceURL as AnyObject).lastPathComponent!)"
guard let strongSelf = self else { return }
strongSelf.storageRef.child(filePath)
.putFile(from: imageFile!, metadata: nil) { (metadata, error) in
if let error = error {
let nsError = error as NSError
print("Error uploading: \(nsError.localizedDescription)")
return
}
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
})
} else {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else { return }
let imageData = UIImageJPEGRepresentation(image, 0.8)
let imagePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg"
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
self.storageRef.child(imagePath)
.putData(imageData!, metadata: metadata) { [weak self] (metadata, error) in
if let error = error {
print("Error uploading: \(error)")
return
}
guard let strongSelf = self else { return }
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
}
}
Uji Pengiriman dan Penerimaan Pesan Gambar
- Klik
Tombol Jalankan .
- Klik Masuk untuk membuka jendela pesan.
- Klik ikon "tambahkan foto" untuk memilih foto. Pesan baru yang berisi foto tersebut akan terlihat di UI aplikasi dan di Firebase console.
10. Selamat!
Anda telah menggunakan Firebase untuk membuat aplikasi chat real-time dengan mudah.
Apa yang telah kami bahas
- Basis Data Waktu Nyata
- Masuk Federasi
- Penyimpanan