1. بررسی اجمالی
به صفحه کد چت دوستانه خوش آمدید. در این کد لبه، یاد خواهید گرفت که چگونه از پلتفرم Firebase برای ایجاد برنامه های iOS استفاده کنید. شما یک کلاینت چت را پیاده سازی کرده و عملکرد آن را با استفاده از Firebase نظارت خواهید کرد.
چیزی که یاد خواهید گرفت
- به کاربران اجازه ورود به سیستم را بدهید.
- داده ها را با استفاده از پایگاه داده بیدرنگ Firebase همگام سازی کنید.
- فایل های باینری را در Firebase Storage ذخیره کنید.
آنچه شما نیاز دارید
- Xcode
- CocoaPods
- یک دستگاه آزمایشی با iOS 8.0 و بالاتر یا شبیه ساز
چگونه از این آموزش استفاده خواهید کرد؟
تجربه خود را از ساخت اپلیکیشن های iOS چگونه ارزیابی می کنید؟
2. کد نمونه را دریافت کنید
مخزن GitHub را از خط فرمان کلون کنید.
$ git clone https://github.com/firebase/codelab-friendlychat-ios
3. برنامه شروع را بسازید
برای ساخت برنامه شروع:
- در یک پنجره ترمینال، به مسیر بروید دایرکتوری
ios-starter/swift-starter
از دانلود کد نمونه شما -
pod install --repo-update
اجرا کنید - فایل FriendlyChatSwift.xcworkspace را باز کنید تا پروژه در Xcode باز شود.
- کلیک کنید بر روی دکمه اجرا
پس از چند ثانیه باید صفحه اصلی گفتگوی دوستانه را ببینید. رابط کاربری باید ظاهر شود. با این حال، در این مرحله نمی توانید وارد سیستم شوید، پیام ارسال یا دریافت کنید. تا زمانی که مرحله بعدی را کامل نکنید، برنامه با یک استثنا لغو می شود.
4. پروژه کنسول Firebase را ایجاد کنید
پروژه ایجاد کنید
از کنسول Firebase گزینه Add Project را انتخاب کنید.
پروژه را FriendlyChat
صدا بزنید، سپس روی Create Project کلیک کنید.
برنامه iOS خود را وصل کنید
- از صفحه نمای کلی پروژه پروژه جدید خود، روی افزودن Firebase به برنامه iOS خود کلیک کنید.
- شناسه بسته را به عنوان "
com.google.firebase.codelab.FriendlyChatSwift
" وارد کنید. - شناسه App Store را به عنوان "
123456
" وارد کنید. - روی ثبت برنامه کلیک کنید.
فایل GoogleService-Info.plist را به برنامه خود اضافه کنید
در صفحه دوم روی Download GoogleService-Info.plist کلیک کنید تا یک فایل پیکربندی که حاوی تمام فراداده های Firebase لازم برای برنامه شما است دانلود شود. آن فایل را در برنامه خود کپی کنید و به هدف FriendlyChatSwift اضافه کنید.
اکنون می توانید بر روی "x" در گوشه سمت راست بالای پنجره کلیک کنید تا آن را ببندید - از مراحل 3 و 4 صرفنظر کنید - همانطور که این مراحل را در اینجا انجام خواهید داد.
وارد کردن ماژول Firebase
با اطمینان از وارد شدن ماژول Firebase
شروع کنید.
AppDelegate.swift ، FCViewController.swift
import Firebase
Firebase را در AppDelegate پیکربندی کنید
از روش "پیکربندی" در FirebaseApp در داخل تابع برنامه:didFinishLaunchingWithOptions برای پیکربندی سرویس های Firebase اساسی از فایل plist. خود استفاده کنید.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance().delegate = self
return true
}
5. شناسایی کاربران
از قوانین برای محدود کردن کاربران احراز هویت شده استفاده کنید
اکنون یک قاعده اضافه می کنیم تا قبل از خواندن یا نوشتن هر پیامی، احراز هویت لازم باشد. برای انجام این کار، قوانین زیر را به شی داده پیام های خود اضافه می کنیم. از داخل بخش Database کنسول Firebase، Realtime Database را انتخاب کنید، سپس روی زبانه Rules کلیک کنید. سپس قوانین را به روز کنید تا به شکل زیر درآیند:
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
برای کسب اطلاعات بیشتر در مورد نحوه کار (از جمله مستندات مربوط به متغیر "auth") به مستندات امنیتی Firebase مراجعه کنید.
API های احراز هویت را پیکربندی کنید
قبل از اینکه برنامه شما بتواند از طرف کاربران به APIهای احراز هویت Firebase دسترسی پیدا کند، باید آن را فعال کنید.
- به کنسول Firebase بروید و پروژه خود را انتخاب کنید
- Authentication را انتخاب کنید
- تب Sign In Method را انتخاب کنید
- سوئیچ Google را روی فعال (آبی) تغییر دهید
- ذخیره را در گفتگوی حاصل فشار دهید
اگر بعداً با پیغام "CONFIGURATION_NOT_FOUND" در این لبه کد خطاهایی دریافت کردید، به این مرحله بازگردید و کار خود را دوباره بررسی کنید.
وابستگی Firebase Auth را تأیید کنید
تأیید کنید که وابستگی های Firebase Auth در فایل Podfile
وجود دارد.
پادفایل
pod 'Firebase/Auth'
Info.plist خود را برای ورود به سیستم Google تنظیم کنید.
شما باید یک طرح URL سفارشی به پروژه XCode خود اضافه کنید.
- پیکربندی پروژه خود را باز کنید: روی نام پروژه در نمای درختی سمت چپ دوبار کلیک کنید. برنامه خود را از بخش TARGETS انتخاب کنید، سپس برگه Info را انتخاب کنید و بخش URL Types را گسترش دهید.
- روی دکمه + کلیک کنید و یک طرح URL برای شناسه مشتری معکوس خود اضافه کنید. برای یافتن این مقدار، فایل پیکربندی GoogleService-Info.plist را باز کنید و به دنبال کلید REVERSED_CLIENT_ID بگردید. مقدار آن کلید را کپی کنید و آن را در کادر URL Schemes در صفحه پیکربندی قرار دهید. فیلدهای دیگر را خالی بگذارید.
- پس از تکمیل، پیکربندی شما باید چیزی شبیه به شکل زیر باشد (اما با مقادیر خاص برنامه شما):
شناسه مشتری را برای ورود به سیستم Google تنظیم کنید
پس از پیکربندی Firebase، میتوانیم از شناسه مشتری برای راهاندازی Google Sign In در روش «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
}
کنترل کننده ورود به سیستم را اضافه کنید
پس از موفقیت آمیز بودن نتیجه ورود به سیستم Google، از حساب برای احراز هویت با 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
}
}
}
به طور خودکار وارد کاربر شوید. سپس یک شنونده به Firebase Auth اضافه کنید تا کاربر پس از ورود موفقیت آمیز به برنامه اجازه ورود به برنامه را بدهد. و شنونده را در 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)
}
}
خروج از سیستم
روش Sign out را اضافه کنید
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)")
}
}
خواندن پیام ها را به عنوان کاربر وارد شده آزمایش کنید
- کلیک کنید بر روی دکمه اجرا
- شما باید فوراً به صفحه ورود به سیستم فرستاده شوید. روی دکمه ورود به سیستم گوگل ضربه بزنید.
- اگر همه چیز به خوبی کار می کرد، باید به صفحه پیام فرستاده شوید.
6. پایگاه داده Realtime را فعال کنید
وارد کردن پیام ها
در پروژه خود در کنسول Firebase مورد پایگاه داده را در نوار ناوبری سمت چپ انتخاب کنید. در منوی سرریز پایگاه داده، Import JSON را انتخاب کنید. به فایل initial_messages.json
در فهرست دوستانه چت بروید، آن را انتخاب کنید و سپس روی دکمه Import کلیک کنید. این جایگزین هر داده ای است که در حال حاضر در پایگاه داده شما وجود دارد. همچنین می توانید پایگاه داده را مستقیماً با استفاده از x سبز + و قرمز برای افزودن و حذف موارد ویرایش کنید.
پس از وارد کردن پایگاه داده شما باید به شکل زیر باشد:
وابستگی پایگاه داده Firebase را تأیید کنید
در بلوک وابستگی های فایل Podfile
، تأیید کنید که Firebase/Database
گنجانده شده است.
پادفایل
pod 'Firebase/Database'
همگام سازی پیام های موجود
کدی را اضافه کنید که پیام های تازه اضافه شده را به رابط کاربری برنامه همگام می کند.
کدی که در این بخش اضافه میکنید:
- پایگاه داده Firebase را راه اندازی کنید و یک شنونده برای مدیریت تغییرات ایجاد شده در پایگاه داده اضافه کنید.
-
DataSnapshot
را به روز کنید تا پیام های جدید نشان داده شود.
متدهای "deinit"، "configureDatabase" و "tableView:cellForRow indexPath:" FCViewController خود را تغییر دهید. کد زیر را جایگزین کنید:
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
}
همگام سازی پیام آزمایشی
- کلیک کنید بر روی دکمه اجرا
- برای رفتن به پنجره پیام ها روی دکمه ورود برای شروع کلیک کنید.
- پیام های جدید را مستقیماً در کنسول Firebase با کلیک بر روی نماد سبز رنگ در کنار ورودی "پیام ها" و اضافه کردن یک شی مانند زیر اضافه کنید:
- تأیید کنید که آنها در رابط کاربری گفتگوی دوستانه نشان داده شوند.
7. ارسال پیام
پیاده سازی ارسال پیام
مقادیر را به پایگاه داده فشار دهید. وقتی از روش فشار برای افزودن داده به پایگاه داده بیدرنگ Firebase استفاده می کنید، یک شناسه خودکار اضافه می شود. این شناسههای تولید شده خودکار متوالی هستند، که تضمین میکند پیامهای جدید به ترتیب صحیح اضافه میشوند.
روش "sendMessage:" FCViewController خود را تغییر دهید. کد زیر را جایگزین کنید:
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)
}
تست ارسال پیام
- کلیک کنید بر روی دکمه اجرا
- برای رفتن به پنجره پیام ها روی Sign In کلیک کنید.
- یک پیام تایپ کنید و ارسال را بزنید. پیام جدید باید در رابط کاربری برنامه و کنسول Firebase قابل مشاهده باشد.
8. ذخیره و دریافت تصاویر
وابستگی Firebase Storage را تأیید کنید
در بلوک وابستگیهای Podfile
، Firebase/Storage
را تأیید کنید.
پادفایل
pod 'Firebase/Storage'
Firebase Storage را در داشبورد فعال کنید
به کنسول Firebase بروید و تأیید کنید که Storage با دامنه "gs://PROJECTID.appspot.com" فعال شده است.
اگر پنجره فعالسازی را میبینید، روی «شروع به کار» کلیک کنید تا با قوانین پیشفرض فعال شود.
FirebaseStorage را پیکربندی کنید
FCViewController.swift
func configureStorage() {
storageRef = Storage.storage().reference()
}
دریافت تصاویر در پیام های موجود
کدی را اضافه کنید که تصاویر را از Firebase Storage بارگیری می کند.
روش "tableView: cellForRowAt indexPath:" FCViewController خود را تغییر دهید. کد زیر را جایگزین کنید:
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. پیام های تصویری ارسال کنید
پیاده سازی فروشگاه و ارسال تصاویر
یک تصویر از کاربر آپلود کنید، سپس URL ذخیره سازی این تصویر را با پایگاه داده همگام کنید تا این تصویر در داخل پیام ارسال شود.
روش "imagePickerController: didFinishPickingMediaWithInfo:" FCViewController خود را تغییر دهید. کد زیر را جایگزین کنید:
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])
}
}
}
تست ارسال و دریافت پیام های تصویری
- کلیک کنید بر روی دکمه اجرا
- برای رفتن به پنجره پیام ها روی Sign In کلیک کنید.
- برای انتخاب عکس روی نماد "افزودن عکس" کلیک کنید. پیام جدید همراه با عکس باید در رابط کاربری برنامه و کنسول Firebase قابل مشاهده باشد.
10. تبریک می گویم!
شما از Firebase برای ایجاد آسان یک برنامه چت بلادرنگ استفاده کرده اید.
آنچه را پوشش داده ایم
- پایگاه داده بیدرنگ
- ورود فدرال
- ذخیره سازی