1. Genel Bakış
Friendly Chat kod laboratuvarına hoş geldiniz. Bu codelab'de iOS uygulamaları oluşturmak için Firebase platformunu nasıl kullanacağınızı öğreneceksiniz. Bir sohbet istemcisi uygulayacak ve Firebase'i kullanarak performansını izleyeceksiniz.
Neler öğreneceksiniz?
- Kullanıcıların oturum açmasına izin verin.
- Firebase Realtime Database'i kullanarak verileri senkronize edin.
- İkili program dosyalarını Firebase Storage'da depolayın.
Gerekenler
- X kodu
- CocoaPods
- iOS 8.0+ veya simülatör yüklü bir test cihazı
Bu eğiticiden nasıl yararlanacaksınız?
iOS uygulaması geliştirme deneyiminizi nasıl değerlendirirsiniz?
2. Örnek kodu alın
GitHub deposunu komut satırından klonlayın.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. Başlangıç uygulamasını oluşturma
Başlangıç uygulamasını oluşturmak için:
- Terminal penceresinde, indirdiğiniz örnek koddan
ios-starter/swift-starter
dizinine gidin. pod install --repo-update
çalıştırma- Projeyi Xcode'da açmak için FriendlyChatSwift.xcworkspace dosyasını açın.
- Çalıştır düğmesini tıklayın.
Birkaç saniye sonra Samimi Sohbet ana ekranı görünecektir. Kullanıcı arayüzü görünür. Ancak bu aşamada oturum açamaz, mesaj gönderip alamazsınız. Sonraki adımı tamamlayana kadar uygulama bir istisnayla iptal edilir.
4. Firebase konsol projesi oluşturma
Proje oluşturma
Firebase konsolunda Proje Ekle'yi seçin.
FriendlyChat
projesini çağırın, ardından Proje Oluştur'u tıklayın.
Firebase fiyatlandırma planınızı yükseltme
Cloud Storage for Firebase'i kullanmak için Firebase projenizin kullandıkça öde (Blaze) fiyatlandırma planı kapsamında olması, yani bir Cloud Faturalandırma hesabına bağlı olması gerekir.
- Cloud Faturalandırma hesabı için kredi kartı gibi bir ödeme yöntemi gerekir.
- Firebase ve Google Cloud'u kullanmaya yeni başladıysanız 300 ABD doları kredi ve Ücretsiz Deneme Cloud Faturalandırma Hesabı için uygun olup olmadığınızı kontrol edin.
- Bu codelab'i bir etkinliğin parçası olarak gerçekleştiriyorsanız düzenleyen kişiye, kullanılabilir Cloud kredisi olup olmadığını sorun.
Projenizi Blaze planına yükseltmek için aşağıdaki adımları uygulayın:
- Firebase konsolunda planınızı yükseltmeyi seçin.
- Blaze planını seçin. Projenize bir Cloud Faturalandırma hesabı bağlamak için ekrandaki talimatları uygulayın.
Bu yükseltme kapsamında bir Cloud Faturalandırma hesabı oluşturmanız gerekiyorsa yükseltmeyi tamamlamak için Firebase Console'daki yükseltme akışına geri dönmeniz gerekebilir.
iOS uygulamanızı bağlama
- Yeni projenizin Projeye Genel Bakış ekranında Firebase'i iOS uygulamanıza ekle'yi tıklayın.
- Paket kimliğini "
com.google.firebase.codelab.FriendlyChatSwift
" olarak girin. - App Store kimliğini "
123456
" olarak girin. - Uygulamayı Kaydet'i tıklayın.
Uygulamanıza GoogleService-Info.plist dosyası ekleme
İkinci ekranda, uygulamanız için gerekli tüm Firebase meta verilerini içeren bir yapılandırma dosyası indirmek üzere GoogleService-Info.plist dosyasını indir'i tıklayın. Bu dosyayı uygulamanıza kopyalayıp FriendlyChatSwift hedefine ekleyin.
Şimdi, 3. ve 4. adımları atlayarak, pop-up'ı kapatmak için sağ üst köşedeki "x" işaretini tıklayabilirsiniz. Bu adımları burada uygulamanız gerekir.
Firebase modülünü içe aktarma
Firebase
modülünün içe aktarıldığından emin olun.
AppDelegate.swift, FCViewController.swift
import Firebase
AppDelegate'de Firebase'i yapılandırma
Temel Firebase hizmetlerini .plist dosyanızdan yapılandırmak için application:didFinishLaunchingWithOptions işlevindeki FirebaseApp'te "configure" yöntemini kullanın.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. Kullanıcıları Tanımlama
Kimlik doğrulanmış kullanıcılarla kısıtlamak için kuralları kullanma
Artık ileti okumadan veya yazmadan önce kimlik doğrulaması yapılmasını gerektirecek bir kural ekleyeceğiz. Bunun için iletiler veri nesnemize aşağıdaki kuralları ekleriz. Firebase Konsolu'nun Veritabanı bölümünden Gerçek Zamanlı Veritabanı'nı seçin ve ardından Kurallar sekmesini tıklayın. Ardından, kuralları aşağıdaki gibi görünecek şekilde güncelleyin:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
Bu sürecin işleyiş şekli hakkında daha fazla bilgi edinmek için ("kimlik doğrulama" değişkeniyle ilgili belgeler dahil), Firebase güvenlik belgelerini inceleyin.
Kimlik doğrulama API'lerini yapılandırma
Uygulamanızın, kullanıcılarınız adına Firebase Authentication API'lerine erişebilmesi için önce bu API'yi etkinleştirmeniz gerekir
- Firebase Konsolu'na gidin ve projenizi seçin.
- Authentication'ı (Kimlik Doğrulama) seçin
- Oturum Açma Yöntemi sekmesini seçin.
- Google anahtarını etkin (mavi) konuma getirin.
- Açılan iletişim kutusunda Kaydet'e basın
Bu codelab'de daha sonra "CONFIGURATION_NOT_FOUND" mesajıyla hata mesajı alırsanız bu adıma dönüp çalışmanızı tekrar kontrol edin.
Firebase Auth bağımlılığını onaylama
Podfile
dosyasında Firebase Auth bağımlılıklarının olduğunu doğrulayın.
Pod dosyası
pod 'Firebase/Auth'
Info.plist dosyanızı Google ile oturum açma için ayarlayın.
XCode projenize özel bir URL şeması eklemeniz gerekir.
- Proje yapılandırmanızı açın: Sol ağaç görünümünde proje adını çift tıklayın. HEDEFLER bölümünden uygulamanızı seçin, ardından Bilgi sekmesini seçin ve URL Türleri bölümünü genişletin.
- + düğmesini tıklayın ve ters çevrilmiş istemci kimliğiniz için bir URL şeması ekleyin. Bu değeri bulmak için GoogleService-Info.plist yapılandırma dosyasını açın ve REVERSED_CLIENT_ID anahtarını bulun. Bu anahtarın değerini kopyalayın ve yapılandırma sayfasındaki URL Şemaları kutusuna yapıştırın. Diğer alanları boş bırakın.
- Yapılandırmanız tamamlandığında aşağıdakine benzer bir şekilde görünmelidir (ancak uygulamaya özgü değerlerinizle):
Google ile oturum açma için clientID ayarlama
Firebase yapılandırıldıktan sonra, "didFinishLaunchingWithOptions:" yönteminde Google ile oturum açma özelliğini ayarlamak için clientID'yi kullanabiliriz.
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
}
Giriş işleyicisini ekleme
Google ile Oturum Açma işleminin sonucu başarılı olduğunda Firebase ile kimlik doğrulamak için hesabı kullanın.
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
}
}
}
Kullanıcının oturumunu otomatik olarak açma Ardından, başarılı bir oturum açtıktan sonra kullanıcının uygulamaya girmesine izin vermek için Firebase Auth'a bir dinleyici ekleyin. Son olarak, dinleyiciyi YouTube'da devre dışı bırakabilirsiniz.
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)
}
}
Oturumu Kapat
Oturumu kapatma yöntemini ekleme
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)")
}
}
İletileri Oturum Açmış Kullanıcı Olarak Test Etme
- Çalıştır düğmesini tıklayın.
- Hemen oturum açma ekranına yönlendirilirsiniz. Google ile oturum açma düğmesine dokunun.
- Her şey yolunda giderse mesajlaşma ekranına yönlendirilirsiniz.
6. Realtime Database'i etkinleştir
Mesajlar'ı içe aktarma
Firebase konsolundaki projenizde, sol gezinme çubuğundan Veritabanı öğesini seçin. Veritabanının taşma menüsünde Import JSON'u (JSON'u İçe Aktar) seçin. Friendlychat dizinindeki initial_messages.json
dosyasına göz atın, dosyayı seçin ve ardından Import (İçe aktar) düğmesini tıklayın. Bu işlemle, şu anda veritabanınızda olan tüm veriler değiştirilir. Ayrıca, öğe ekleyip kaldırmak için yeşil + ve kırmızı x işaretlerini kullanarak veritabanını doğrudan düzenleyebilirsiniz.
İçe aktarma işleminden sonra veritabanınız şu şekilde görünecektir:
Firebase veritabanı bağımlılığını onaylama
Podfile
dosyasının bağımlılıklar bloğunda Firebase/Database
'un dahil edildiğinden emin olun.
Pod dosyası
pod 'Firebase/Database'
Mevcut İletileri Senkronize Etme
Yeni eklenen mesajları uygulamanın kullanıcı arayüzüne senkronize eden bir kod ekleyin.
Bu bölüme ekleyeceğiniz kod:
- Firebase veritabanını başlatın ve veritabanında yapılan değişiklikleri işlemek için bir dinleyici ekleyin.
- Yeni mesajların gösterilebilmesi için
DataSnapshot
uygulamasını güncelleyin.
FCViewController'ınızın "deinit", "configureDatabase" ve "tableView:cellForRow indexPath:" yöntemlerini değiştirin; aşağıdaki kodla değiştirin:
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
}
Mesaj senkronizasyonunu test etme
- Çalıştır düğmesini tıklayın.
- Mesajlar penceresine gitmek için Başlamak için oturum açın düğmesini tıklayın.
- "Mesajlar" girişinin yanındaki yeşil + simgesini tıklayıp aşağıdakine benzer bir nesne ekleyerek doğrudan Firebase konsolunda yeni mesajlar ekleyin:
- Dost Canlısı Sohbet Kullanıcı Arayüzünde göründüğünü doğrulayın.
7. Mesajlar Gönderme
Mesaj Gönderme özelliğini uygulama
Değerleri veritabanına aktarın. Firebase Realtime Database'e veri eklemek için push yöntemini kullandığınızda otomatik bir kimlik eklenir. Otomatik olarak oluşturulan bu kimlikler sıralı olduğundan yeni iletilerin doğru sırayla eklenmesi sağlanır.
FCViewController'ınızın "sendMessage:" yöntemini değiştirin ve aşağıda tanımlanan kodla değiştirin:
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)
}
Mesaj Gönderme İşlemini Test Etme
- Çalıştır düğmesini tıklayın.
- Mesajlar penceresine gitmek için Oturum Aç'ı tıklayın.
- Mesajınızı yazın ve Gönder'e basın. Yeni mesaj, uygulama kullanıcı arayüzünde ve Firebase konsolunda görünür olmalıdır.
8. Resim depolama ve alma
Firebase Storage Bağımlılığını Onaylama
Podfile
öğesinin bağımlılıklar bloğunda Firebase/Storage
'un dahil edildiğinden emin olun.
Pod dosyası
pod 'Firebase/Storage'
Cloud Storage for Firebase'i ayarlama
Firebase projenizde Cloud Storage for Firebase'i ayarlamak için:
- Firebase konsolunun sol panelinde Derleme'yi genişletin ve ardından Depolama'yı seçin.
- Başlayın'ı tıklayın.
- Varsayılan Storage paketiniz için bir konum seçin.
US-WEST1
,US-CENTRAL1
veUS-EAST1
bölgelerindeki paketler, Google Cloud Storage için "Daima Ücretsiz" katmanından yararlanabilir. Diğer tüm konumlardaki paketler için Google Cloud Storage fiyatlandırması ve kullanımı geçerlidir. - Test modunda başlat'ı tıklayın. Güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyun.
Bu codelab'in ilerleyen bölümlerinde, verilerinizin güvenliğini sağlamak için güvenlik kuralları ekleyeceksiniz. Depolama alanı paketiniz için Güvenlik Kuralları eklemedenbir uygulamayı dağıtmayın veya herkese açık olarak göstermeyin. - Oluştur'u tıklayın.
FirebaseStorage'ı yapılandırma
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
Mevcut mesajlarda resim alma
Firebase Storage'dan resim indiren bir kod ekleyin.
FCViewController'ınızın "tableView: CellForRowAt indexPath:" yöntemini değiştirin ve aşağıda tanımlanan kodla değiştirin:
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. Resim mesajları gönderme
Mağazayı Uygulama ve Resimleri Gönderme
Kullanıcıdan bir resim yükleyin, ardından bu resmin depolama alanı URL'sini veritabanıyla senkronize edin. Böylece resim, ileti içinde gönderilir.
FCViewController'ınızın "image PickerController: didFinish PickingMediaWithInfo:" yöntemini belirleyin. Bunu aşağıda tanımlanan kodla değiştirin:
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])
}
}
}
Resim Mesajları Gönderme ve Alma Testi
- Çalıştır düğmesini tıklayın.
- Mesajlar penceresine gitmek için Oturum aç'ı tıklayın.
- Fotoğraf seçmek için "Fotoğraf ekle" simgesini tıklayın. Fotoğrafın yer aldığı yeni mesaj, uygulama kullanıcı arayüzünde ve Firebase konsolunda görünür.
10. Tebrikler!
Gerçek zamanlı sohbet uygulaması oluşturmak için Firebase'i kolayca kullandınız.
İşlediklerimiz
- Realtime Database
- Birleşik Oturum Açma
- Depolama