Firebase iOS Codelab Swift

1. نظرة عامة

2efe6805ef369641.png

مرحبًا بك في مختبر كود الدردشة الودية. في مختبر الرموز هذا ، ستتعلم كيفية استخدام نظام Firebase الأساسي لإنشاء تطبيقات iOS. ستقوم بتنفيذ برنامج دردشة ومراقبة أدائه باستخدام Firebase.

مختبر الرموز هذا متاح أيضًا في Objective-C.

ماذا ستتعلم

  • السماح للمستخدمين بتسجيل الدخول.
  • مزامنة البيانات باستخدام قاعدة بيانات Firebase Realtime.
  • تخزين الملفات الثنائية في Firebase Storage.

ماذا ستحتاج

  • Xcode
  • CocoaPods
  • جهاز اختبار يعمل بنظام iOS 8.0+ أو جهاز محاكاة

كيف ستستخدم هذا البرنامج التعليمي؟

اقرأها فقط اقرأها وأكمل التدريبات

كيف تقيم تجربتك مع إنشاء تطبيقات iOS؟

مبتدئ متوسط بارع

2. احصل على نموذج التعليمات البرمجية

استنساخ مستودع GitHub من سطر الأوامر.

$ git clone https://github.com/firebase/codelab-friendlychat-ios

3. بناء التطبيق المبدئي

2f4c98d858c453fe.png

لإنشاء تطبيق المبتدئين:

  1. في نافذة طرفية ، انتقل إلى ملف android_studio_folder.png ios-starter/swift-starter الدليل من الخاصة بك نموذج التعليمات البرمجية تحميل
  2. تشغيل pod install --repo-update
  3. افتح ملف FriendlyChatSwift.xcworkspace لفتح المشروع في Xcode.
  4. انقر على 98205811bbed9d74.png زر التشغيل.

يجب أن تشاهد الشاشة الرئيسية للمحادثة الودية تظهر بعد بضع ثوان. يجب أن تظهر واجهة المستخدم. ومع ذلك ، في هذه المرحلة ، لا يمكنك تسجيل الدخول أو إرسال أو استقبال الرسائل. سيتم إيقاف التطبيق باستثناء استثناء حتى تكمل الخطوة التالية.

4. إنشاء مشروع وحدة تحكم Firebase

أنشئ مشروعًا

من وحدة التحكم Firebase حدد إضافة Project.

استدعاء مشروع FriendlyChat ، ثم انقر فوق إنشاء مشروع.

لقطة شاشة من 2015-11-06 14:13: 39.png

قم بتوصيل تطبيق iOS الخاص بك

  1. من لمحة عن المشروع شاشة المشروع الجديد الخاص بك، انقر فوق إضافة Firebase لتطبيقات نظام التشغيل iOS الخاص بك.
  2. أدخل رمز الرزمة، و" com.google.firebase.codelab.FriendlyChatSwift ".
  3. أدخل معرف المتجر باسم " 123456 ".
  4. انقر فوق تسجيل التطبيقات.

أضف ملف GoogleService-Info.plist إلى تطبيقك

على الشاشة إضغط الثاني تحميل GoogleService-Info.plist لتحميل ملف التكوين الذي يحتوي على كافة البيانات الوصفية Firebase اللازمة للتطبيق. نسخ هذا الملف إلى التطبيق الخاص بك وإضافته إلى الهدف FriendlyChatSwift.

يمكنك الآن النقر فوق "x" في الزاوية اليمنى العليا من النافذة المنبثقة لإغلاقها - تخطي الخطوتين 3 و 4 - حيث ستنفذ هاتين الخطوتين هنا.

19d59efb213ddbdc.png

استيراد وحدة 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. تحديد المستخدمين

استخدم القواعد لتقييد المستخدمين المصادق عليهم

سنضيف الآن قاعدة لطلب المصادقة قبل قراءة أو كتابة أي رسائل. للقيام بذلك ، نضيف القواعد التالية إلى كائن بيانات الرسائل. من داخل قسم قاعدة البيانات من وحدة التحكم Firebase تحديد قاعدة البيانات في الوقت الحقيقي، ثم انقر فوق علامة التبويب القواعد. ثم قم بتحديث القواعد بحيث تبدو كما يلي:

{
  "rules": {
    "messages": {
      ".read": "auth != null",
      ".write": "auth != null"
    }
  }
}

لمزيد من المعلومات حول كيفية عمل هذه (بما في ذلك الوثائق على المتغير "المصادقة") انظر Firebase وثائق الأمن .

تكوين مصادقة واجهات برمجة التطبيقات

قبل أن يتمكن تطبيقك من الوصول إلى واجهات برمجة تطبيقات مصادقة Firebase نيابة عن المستخدمين ، سيتعين عليك تمكينها

  1. انتقل إلى وحدة التحكم Firebase وحدد مشروعك
  2. مصادقة حدد
  3. حدد تسجيل علامة التبويب الطريقة في
  4. تبديل مفتاح جوجل لتمكين (الأزرق)
  5. حفظ اضغط على الحوار الناتج

إذا ظهرت لك أخطاء لاحقًا في مختبر الشفرات هذا مع الرسالة "CONFIGURATION_NOT_FOUND" ، فارجع إلى هذه الخطوة وتحقق مرة أخرى من عملك.

قم بتأكيد تبعية Firebase Auth

توجد تبعيات تأكيد Firebase أصيل في Podfile الملف.

بودفيلي

pod 'Firebase/Auth'

قم بإعداد Info.plist الخاص بك لتسجيل الدخول إلى Google.

ستحتاج إلى إضافة مخطط URL مخصص إلى مشروع XCode الخاص بك.

  1. افتح تكوين المشروع الخاص بك: انقر نقرًا مزدوجًا فوق اسم المشروع في عرض الشجرة الأيسر. حدد التطبيق الخاص بك من قسم الأهداف ، ثم حدد علامة التبويب المعلومات ، وقم بتوسيع قسم أنواع عناوين URL.
  2. انقر فوق الزر + ، وأضف مخطط URL لمعرف العميل المعكوس. للعثور على هذه القيمة ، افتح ملف تكوين GoogleService-Info.plist ، وابحث عن مفتاح REVERSED_CLIENT_ID. انسخ قيمة هذا المفتاح ، والصقها في مربع أنظمة URL في صفحة التكوين. اترك الحقول الأخرى فارغة.
  3. عند الانتهاء ، يجب أن يبدو التكوين الخاص بك مشابهًا لما يلي (ولكن مع القيم الخاصة بالتطبيق):

1b54d5bd2f4f1448.png

قم بتعيين معرف العميل لتسجيل الدخول إلى Google

بعد تهيئة Firebase ، يمكننا استخدام معرّف العميل لإعداد تسجيل الدخول إلى Google داخل طريقة "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)
    }
  }

خروج

أضف طريقة تسجيل الخروج

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)")
    }
  }

اختبر قراءة الرسائل كمستخدم مسجل الدخول

  1. انقر على 98205811bbed9d74.png زر التشغيل.
  2. يجب أن يتم إرسالك على الفور إلى شاشة تسجيل الدخول. اضغط على زر Google Sign-In.
  3. يجب أن يتم إرسالك بعد ذلك إلى شاشة المراسلة إذا كان كل شيء يعمل بشكل جيد.

6. تفعيل Realtime Database

2efe6805ef369641.png

استيراد الرسائل

في المشروع في وحدة التحكم Firebase حدد العنصر قاعدة البيانات في شريط التنقل الأيمن. في القائمة الكاملة من قاعدة البيانات حدد استيراد JSON. استعرض للوصول إلى initial_messages.json الملف في الدليل friendlychat، حدده ثم انقر فوق الزر استيراد. سيؤدي هذا إلى استبدال أي بيانات موجودة حاليًا في قاعدة البيانات الخاصة بك. يمكنك أيضًا تحرير قاعدة البيانات مباشرةً ، باستخدام الأخضر + والأحمر x لإضافة العناصر وإزالتها.

20ccf4856b715b4c.png

بعد استيراد قاعدة البيانات الخاصة بك يجب أن تبدو كما يلي:

f3e0367f1c9cd187.png

تأكيد تبعية قاعدة بيانات Firebase

في كتلة تبعيات Podfile الملف، تؤكد أن Firebase/Database يتم تضمين.

بودفيلي

pod 'Firebase/Database'

مزامنة الرسائل الموجودة

أضف رمزًا يزامن الرسائل المضافة حديثًا إلى واجهة مستخدم التطبيق.

الرمز الذي تضيفه في هذا القسم سوف:

  • قم بتهيئة قاعدة بيانات Firebase وإضافة مستمع للتعامل مع التغييرات التي تم إجراؤها على قاعدة البيانات.
  • تحديث DataSnapshot ذلك سيتم عرض الرسائل الجديدة.

تعديل "deinit" و "configurationDatabase" و "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
  }

اختبار مزامنة الرسائل

  1. انقر على 98205811bbed9d74.png زر التشغيل.
  2. انقر على تسجيل الدخول للحصول على زر بدأت في الذهاب إلى إطار الرسائل.
  3. أضف رسائل جديدة مباشرةً في وحدة تحكم Firebase بالنقر فوق الرمز الأخضر + بجوار إدخال "الرسائل" وإضافة كائن مثل ما يلي: f9876ffc8b316b14.png
  4. تأكد من ظهورهم في واجهة مستخدم الدردشة الودية.

7. إرسال الرسائل

تنفيذ إرسال رسالة

دفع القيم إلى قاعدة البيانات. عند استخدام طريقة الدفع لإضافة بيانات إلى قاعدة بيانات Firebase Realtime ، ستتم إضافة معرف تلقائي. هذه المعرفات التي يتم إنشاؤها تلقائيًا هي متسلسلة ، مما يضمن إضافة الرسائل الجديدة بالترتيب الصحيح.

تعديل طريقة "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)
  }

اختبار إرسال الرسائل

  1. انقر على 98205811bbed9d74.png زر التشغيل.
  2. انقر فوق تسجيل الدخول للذهاب إلى إطار الرسائل.
  3. اكتب رسالة واضغط على إرسال. يجب أن تكون الرسالة الجديدة مرئية في واجهة مستخدم التطبيق وفي وحدة تحكم Firebase.

8. تخزين الصور واستلامها

تأكيد تبعية تخزين Firebase

في كتلة تبعيات Podfile ، أكد Firebase/Storage يتم تضمين.

بودفيلي

pod 'Firebase/Storage'

قم بتنشيط تخزين Firebase في لوحة القيادة

انتقل إلى وحدة تحكم Firebase وتأكد من تنشيط التخزين باستخدام المجال "gs: //PROJECTID.appspot.com"

b0438b37a588bcee.png

إذا كنت ترى نافذة التنشيط بدلاً من ذلك ، فانقر فوق "البدء" لتنشيطها بالقواعد الافتراضية.

c290bbebff2cafa7.png

هيئ 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])
      }
    }
  }

اختبار إرسال واستلام رسائل الصور

  1. انقر على 98205811bbed9d74.png زر التشغيل.
  2. انقر فوق تسجيل الدخول للذهاب إلى إطار الرسائل.
  3. انقر فوق رمز "إضافة صورة" لاختيار صورة. يجب أن تكون الرسالة الجديدة بالصورة مرئية في واجهة مستخدم التطبيق وفي وحدة تحكم Firebase.

10. مبروك!

لقد استخدمت Firebase لإنشاء تطبيق دردشة في الوقت الفعلي بسهولة.

ما غطينا

  • قاعدة بيانات الوقت الفعلي
  • تسجيل الدخول الموحد
  • تخزين

يتعلم أكثر