Google은 흑인 공동체를 위한 인종적 평등을 추구하기 위해 노력하고 있습니다. 자세히 알아보기

Firebase iOS Codelab 스위프트

2efe6805ef369641.png

친절한 채팅 코드랩에 오신 것을 환영합니다. 이 코드랩에서는 Firebase 플랫폼을 사용하여 iOS 애플리케이션을 만드는 방법을 배웁니다. Firebase를 사용하여 채팅 클라이언트를 구현하고 성능을 모니터링합니다.

이 코드랩은 Objective-C에서도 사용할 수 있습니다.

배울 내용

  • 사용자가 로그인하도록 허용합니다.
  • Firebase 실시간 데이터베이스를 사용하여 데이터를 동기화합니다.
  • Firebase 저장소에 바이너리 파일을 저장합니다.

필요한 것

  • 엑스코드
  • 코코아팟
  • iOS 8.0+ 또는 시뮬레이터가 설치된 테스트 기기

이 튜토리얼을 어떻게 사용하시겠습니까?

통해서만 읽어보세요 그것을 읽고 연습을 완료하십시오

iOS 앱 구축 경험을 평가해 주세요.

초심자 중급 능숙

명령줄에서 GitHub 리포지토리를 복제합니다.

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

2f4c98d858c453fe.png

스타터 앱을 빌드하려면:

  1. 터미널 창에서 android_studio_folder.png ios-starter/swift-starter 샘플 코드를 다운로드 한 디렉토리
  2. 실행이 pod install --repo-update
  3. Xcode에서 프로젝트를 열려면 FriendlyChatSwift.xcworkspace 파일을 엽니다.
  4. 클릭 98205811bbed9d74.png 실행 버튼을 클릭합니다.

몇 초 후에 친절한 채팅 홈 화면이 표시되어야 합니다. UI가 나타나야 합니다. 그러나 이 시점에서는 로그인하거나 메시지를 보내거나 받을 수 없습니다. 다음 단계를 완료할 때까지 앱이 예외적으로 중단됩니다.

프로젝트 생성

에서 중포 기지 콘솔 프로젝트 추가를 선택합니다.

프로젝트 전화 FriendlyChat 다음 클릭 프로젝트를 만듭니다.

2015-11-06 14:13:39.png의 스크린샷

iOS 앱 연결

  1. 새 프로젝트의 사업 개요 화면에서 클릭하여 iOS 앱에 중포 기지를 추가합니다.
  2. "로, 번들 ID를 입력 com.google.firebase.codelab.FriendlyChatSwift ".
  3. "로 앱 스토어 ID를 입력 123456 ".
  4. 등록 앱을 클릭합니다.

앱에 GoogleService-Info.plist 파일 추가

두 번째 화면의 다운로드를 클릭에 GoogleService-의 Info.plist는 모든 응용 프로그램에 필요한 중포 기지 메타 데이터를 포함하는 구성 파일을 다운로드합니다. 응용 프로그램에 해당 파일을 복사하고 FriendlyChatSwift 대상에 추가합니다.

이제 팝업의 오른쪽 상단 모서리에 있는 "x"를 클릭하여 팝업을 닫을 수 있습니다. 여기에서 해당 단계를 수행하므로 3단계와 4단계를 건너뜁니다.

19d59efb213ddbdc.png

Firebase 모듈 가져오기

확인함으로써 시작 Firebase 모듈을 가져옵니다.

AppDelegate.swift , FCViewController.swift

import Firebase

AppDelegate에서 Firebase 구성

application:didFinishLaunchingWithOptions 함수 내 FirebaseApp의 "configure" 메서드를 사용하여 .plist 파일에서 기본 Firebase 서비스를 구성합니다.

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions
      launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  FirebaseApp.configure()
  GIDSignIn.sharedInstance().delegate = self
  return true
}

규칙을 사용하여 인증된 사용자로 제한

이제 메시지를 읽거나 쓰기 전에 인증을 요구하는 규칙을 추가합니다. 이를 위해 메시지 데이터 개체에 다음 규칙을 추가합니다. 의 데이터베이스 섹션 내에서 중포 기지 콘솔 다음, 실시간 데이터베이스를 선택 규칙 탭을 클릭합니다. 그런 다음 규칙을 업데이트하여 다음과 같이 표시합니다.

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

(이하 "인증"변수에 대한 문서를 포함)이 작품은 중포 기지의 표시 방법에 대한 자세한 내용은 보안 문서를 작성 .

인증 API 구성

애플리케이션이 사용자를 대신하여 Firebase 인증 API에 액세스하려면 먼저 활성화해야 합니다.

  1. 받는 이동 중포 기지 콘솔 및 프로젝트를 선택
  2. 선택 인증
  3. 로그인에서 방법 탭을 선택합니다
  4. 활성화 (파란색)에 구글 스위치 전환
  5. 결과 대화 상자에서 저장을 눌러

나중에 이 코드랩에서 "CONFIGURATION_NOT_FOUND" 메시지와 함께 오류가 발생하면 이 단계로 돌아와 작업을 다시 확인하세요.

Firebase 인증 종속성 확인

확인 중포 기지 인증 종속성이 존재 Podfile 파일.

포드파일

pod 'Firebase/Auth'

Google 로그인을 위한 Info.plist를 설정합니다.

XCode 프로젝트에 사용자 정의 URL 스키마를 추가해야 합니다.

  1. 프로젝트 구성을 엽니다. 왼쪽 트리 보기에서 프로젝트 이름을 두 번 클릭합니다. 대상 섹션에서 앱을 선택한 다음 정보 탭을 선택하고 URL 유형 섹션을 확장합니다.
  2. + 버튼을 클릭하고 역방향 클라이언트 ID에 대한 URL 구성표를 추가합니다. 이 값을 찾으려면 GoogleService-Info.plist 구성 파일을 열고 REVERSED_CLIENT_ID 키를 찾으십시오. 해당 키의 값을 복사하여 구성 페이지의 URL 구성표 상자에 붙여넣습니다. 다른 필드는 비워 둡니다.
  3. 완료되면 구성이 다음과 유사하게 표시되어야 합니다(단, 애플리케이션별 값 포함).

1b54d5bd2f4f1448.png

Google 로그인에 대한 클라이언트 ID 설정

Firebase가 구성되면 clientID를 사용하여 "didFinishLaunchingWithOptions:" 메서드 내에서 Google 로그인을 설정할 수 있습니다.

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 인증에 리스너를 추가하여 로그인에 성공한 후 사용자가 앱에 들어갈 수 있도록 합니다. 그리고 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 로그인 버튼을 탭합니다.
  3. 그런 다음 모든 것이 제대로 작동하면 메시징 화면으로 보내져야 합니다.

2efe6805ef369641.png

메시지 가져오기

당신의 프로젝트에서 중포 기지 콘솔 왼쪽 탐색 모음에서 데이터베이스 항목을 선택합니다. 데이터베이스의 오버 플로우 메뉴에서 가져 오기 JSON을 선택합니다. 받는 사람 찾아 initial_messages.json friendlychat 디렉토리에있는 파일은 다음 가져 오기 버튼을 클릭하여 선택합니다. 이것은 현재 데이터베이스에 있는 모든 데이터를 대체합니다. 녹색 + 및 빨간색 x를 사용하여 항목을 추가 및 제거하여 데이터베이스를 직접 편집할 수도 있습니다.

20ccf4856b715b4c.png

데이터베이스를 가져온 후 다음과 같아야 합니다.

f3e0367f1c9cd187.png

Firebase 데이터베이스 종속성 확인

의 종속성 블록에서 Podfile 파일을 확인하는 것이 Firebase/Database 포함되어 있습니다.

포드파일

pod 'Firebase/Database'

기존 메시지 동기화

새로 추가된 메시지를 앱 UI에 동기화하는 코드를 추가합니다.

이 섹션에 추가하는 코드는 다음과 같습니다.

  • Firebase 데이터베이스를 초기화하고 데이터베이스의 변경 사항을 처리할 리스너를 추가합니다.
  • 업데이트 DataSnapshot 새 메시지가 표시됩니다 있도록.

FCViewController의 "deinit", "configureDatabase" 및 "tableView:cellForRow indexPath:" 메서드를 수정합니다. 아래에 정의된 코드로 바꿉니다.

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. "messages" 항목 옆에 있는 녹색 + 기호를 클릭하고 다음과 같은 객체를 추가하여 Firebase 콘솔에서 직접 새 메시지를 추가합니다. f9876ffc8b316b14.png
  4. 친절 채팅 UI에 표시되는지 확인합니다.

메시지 보내기 구현

값을 데이터베이스에 푸시합니다. 푸시 방식을 사용하여 Firebase 실시간 데이터베이스에 데이터를 추가하면 자동 ID가 추가됩니다. 이러한 자동 생성 ID는 순차적이므로 새 메시지가 올바른 순서로 추가됩니다.

FCViewController의 "sendMessage:" 메소드를 수정하십시오. 아래에 정의된 코드로 바꿉니다.

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. 메시지를 입력하고 보내기를 누르십시오. 새 메시지는 앱 UI와 Firebase 콘솔에 표시되어야 합니다.

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 저장소에서 이미지를 다운로드하는 코드를 추가합니다.

FCViewController의 "tableView: cellForRowAt indexPath:" 메소드를 수정하십시오. 아래에 정의된 코드로 바꿉니다.

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
  }

이미지 저장 및 전송 구현

사용자로부터 이미지를 업로드한 다음 이 이미지의 저장 URL을 데이터베이스에 동기화하여 이 이미지가 메시지 내에서 전송되도록 합니다.

FCViewController의 "imagePickerController: didFinishPickingMediaWithInfo:" 메소드를 수정하십시오. 아래에 정의된 코드로 바꿉니다.

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. 사진을 선택하려면 "사진 추가" 아이콘을 클릭하십시오. 사진이 포함된 새 메시지가 앱 UI와 Firebase 콘솔에 표시되어야 합니다.

Firebase를 사용하여 실시간 채팅 애플리케이션을 쉽게 구축했습니다.

우리가 다룬 내용

  • 실시간 데이터베이스
  • 연합 로그인
  • 저장

더 알아보기