Firebase Data Connect ile geliştirme yapma (iOS / Swift)

1. Genel Bakış

Bu codelab'de, SwiftUI kullanarak iOS için bir film inceleme uygulaması oluşturmak üzere Firebase Data Connect'i Cloud SQL veritabanıyla entegre etme süreci adım adım açıklanmaktadır.

Firebase Data Connect'i kullanarak iOS uygulamanızı Cloud SQL veritabanına bağlamayı ve film incelemeleri için sorunsuz veri senkronizasyonu sağlamayı öğreneceksiniz.

Bu codelab'in sonunda, kullanıcıların filmlere göz atmasına ve filmleri favori olarak işaretlemesine olanak tanıyan, Firebase Data Connect'in gücüyle Cloud SQL veritabanı tarafından desteklenen işlevsel bir iOS uygulamasına sahip olacaksınız.

Neler öğreneceksiniz?

Bu codelab'de şunları öğreneceksiniz:

  • Hızlı geri dönüş süreleri için Firebase Emulator Suite'i kullanarak Firebase Data Connect'i kurun.
  • Data Connect ve GraphQL kullanarak veritabanı şeması tasarlama
  • Veritabanı şemanızdan tür güvenli bir Swift SDK'sı oluşturun ve bunu bir Swift uygulamasına ekleyin.
  • Kullanıcı kimlik doğrulamasını uygulayın ve kullanıcılarınızın verilerini güvence altına almak için Firebase Data Connect ile entegre edin.
  • GraphQL tarafından desteklenen sorgular ve mutasyonlar kullanarak Cloud SQL'deki verileri alın, güncelleyin, silin ve yönetin.
  • (İsteğe bağlı) Bir Data Connect hizmetini üretime dağıtın.

Ön koşullar

  • Xcode'un en son sürümü
  • Codelab'in örnek kodu. Örnek kodu, codelab'in ilk adımlarından birinde indireceksiniz.

2. Örnek projeyi oluşturma

Firebase projesi oluşturma

  1. Google Hesabınızı kullanarak Firebase konsolunda oturum açın.
  2. Yeni bir proje oluşturmak için düğmeyi tıklayın ve ardından bir proje adı girin (örneğin, Friendly Flix).
  3. Devam'ı tıklayın.
  4. İstenirse Firebase şartlarını inceleyip kabul edin ve Devam'ı tıklayın.
  5. (İsteğe bağlı) Firebase konsolunda yapay zeka yardımını etkinleştirin ("Firebase'de Gemini" olarak adlandırılır).
  6. Bu codelab için Google Analytics'e ihtiyacınız yoktur. Bu nedenle, Google Analytics seçeneğini devre dışı bırakın.
  7. Proje oluştur'u tıklayın, projenizin hazırlanmasını bekleyin ve ardından Devam'ı tıklayın.

Kodu indirme

Bu codelab'in örnek kodunu klonlamak için aşağıdaki komutu çalıştırın. Bu işlem, makinenizde codelab-dataconnect-ios adlı bir dizin oluşturur:

git clone https://github.com/FirebaseExtended/codelab-dataconnect-ios`

Bilgisayarınızda git yoksa kodu doğrudan GitHub'dan da indirebilirsiniz.

Firebase yapılandırması ekleme

Firebase SDK, Firebase projenize bağlanmak için bir yapılandırma dosyası kullanır. Apple platformlarında bu dosya GoogleServices-Info.plist olarak adlandırılır. Bu adımda, yapılandırma dosyasını indirip Xcode projenize ekleyeceksiniz.

  1. Firebase konsolunda soldaki gezinme menüsünden Project Overview'ı (Proje Genel Bakışı) seçin.
  2. Platformu seçmek için iOS+ düğmesini tıklayın. Apple paket kimliği istendiğinde com.google.firebase.samples.FriendlyFlix kullanın.
  3. Uygulamayı kaydet'i tıklayın ve GoogleServices-Info.plist dosyasını indirme talimatlarını uygulayın.
  4. İndirilen dosyayı, az önce indirdiğiniz kodun start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/ dizinine taşıyın ve mevcut GoogleServices-Info.plist dosyanın yerine koyun.
  5. Ardından, Firebase konsolunda kurulum projesini tamamlamak için birkaç kez İleri'yi tıklayın (SDK'yı uygulamaya eklemeniz gerekmez. Bu işlem, başlangıç projesinde sizin için zaten yapılmıştır).
  6. Son olarak, kurulum sürecini tamamlamak için Konsola git'i tıklayın.

3. Data Connect'i ayarlama

Kurulum

Otomatik yükleme

codelab-dataconnect-ios/FriendlyFlix dizininde aşağıdaki komutu çalıştırın:

curl -sL https://firebase.tools/dataconnect | bash

Bu komut dosyası, geliştirme ortamını sizin için ayarlamaya ve tarayıcı tabanlı bir IDE başlatmaya çalışır. Bu IDE, şemanızı yönetmenize, uygulamanızda kullanılacak sorguları ve mutasyonları tanımlamanıza ve kesin olarak türlenmiş SDK'lar oluşturmanıza yardımcı olmak için önceden paketlenmiş bir VS Code uzantısı da dahil olmak üzere araçlar sunar.

Komut dosyası çalıştırıldıktan sonra VS Code otomatik olarak açılmalıdır.

Bu işlemi bir kez yaptıktan sonra VS Code'u yerel dizinde çalıştırarak başlatabilirsiniz:

code .

Manuel yükleme

  1. Visual Studio Code'u yükleyin.
  2. Node.js'yi yükleyin.
  3. VS Code'da codelab-dataconnect-ios/FriendlyFlix dizinini açın.
  4. Visual Studio Code Marketplace'ten Firebase Data Connect uzantısını yükleyin.

Projede Data Connect'i başlatma

Sol panelde Firebase simgesini tıklayarak Data Connect VS Code uzantısı kullanıcı arayüzünü açın.

  1. Google ile oturum aç düğmesini tıklayın. Bir tarayıcı penceresi açılır. Google Hesabınızla uzantıda oturum açmak için talimatları uygulayın.
  2. Firebase projesi bağla düğmesini tıklayın ve daha önce konsolda oluşturduğunuz projeyi seçin.
  3. Run firebase init (Firebase'i başlat) düğmesini tıklayın ve entegre terminaldeki adımları uygulayın.

SDK oluşturmayı yapılandırma

Run firebase init (Firebase'i başlat) düğmesini tıkladığınızda Firebase Data Connect uzantısı sizin için bir dataconnect dizini başlatır.

VS Code'da dataconnect/connector/connector.yaml dosyasını açtığınızda varsayılan yapılandırmayı görürsünüz.

Lütfen yapılandırmayı güncelleyin ve oluşturulan kodun bu codelab ile çalıştığından emin olmak için aşağıdaki ayarları kullanın. Özellikle connectorId değerinin friendly-flix, Swift paketinin ise FriendlyFlixSDK olarak ayarlandığından emin olun.

connectorId: "friendly-flix"
generate:
  swiftSdk:
    outputDir: "../../app"
    package: "FriendlyFlixSDK"
    observablePublisher: observableMacro

Bu ayarların anlamı şöyledir:

  • connectorId: Bu bağlayıcı için benzersiz bir ad.
  • outputDir: Oluşturulan Data Connect SDK'sının saklanacağı yol. Bu yol, connector.yaml dosyasını içeren dizine göre belirlenir.
  • package: Oluşturulan Swift paketi için kullanılacak paket adı.

Bu dosyayı kaydettiğinizde Firebase Data Connect, sizin için FriendlyFlixSDK adlı bir Swift paketi oluşturur ve bunu FriendlyFlix proje klasörünün yanına yerleştirir.

Firebase emülatörlerini başlatma

VS Code'da Firebase görünümüne geçin ve Emülatörleri başlat düğmesini tıklayın.

Bu işlem, entegre terminalde Firebase Emulator'ı başlatır. Çıkış şu şekilde görünmelidir:

npx -y firebase-tools@latest emulators:start --project <your-project-id>

Oluşturulan paketi Swift uygulamanıza ekleyin

  1. FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj dosyasını Xcode'da açın
  2. Dosya > Paket Bağımlılıkları Ekle... seçeneğini belirleyin.
  3. Yerel Ekle...'yi tıklayın, ardından FriendlyFlix/app klasöründen FriendlyFlixSDK paketini ekleyin.
  4. Xcode'un paket bağımlılıklarını çözmesini bekleyin.
  5. Choose Package Products for FriendlyFlixSDK (FriendlyFlixSDK için Paket Ürünleri Seçin) iletişim kutusunda hedef olarak FriendlyFlix simgesini seçin ve Add Package (Paket Ekle) seçeneğini tıklayın.

iOS uygulamasını yerel emülatörü kullanacak şekilde yapılandırma

  1. FriendlyFlixApp.swift adlı görüşmeyi açın. (Hızlı Aç iletişim kutusunu açmak için CMD + Üst Karakter + O tuşlarına basabilir, ardından dosyayı hızlıca bulmak için "FriendlyFlixApp" yazabilirsiniz.)
  2. Firebase, Firebase Auth, Firebase Data Connect ve şemanız için oluşturulan SDK'yı içe aktarın.
  3. Başlatıcıda Firebase'i yapılandırın.
  4. DataConnect ve Firebase Auth'un yerel emülatörü kullandığından emin olun.
import SwiftUI
import os
import Firebase
import FirebaseAuth
import FriendlyFlixSDK
import FirebaseDataConnect

@main
struct FriendlyFlixApp: App {
  ...

  init() {
    FirebaseApp.configure()
    if useEmulator {
      DataConnect.friendlyFlixConnector.useEmulator(port: 9399)
      Auth.auth().useEmulator(withHost: "localhost", port: 9099)
    }

    authenticationService = AuthenticationService()
  }

  ...

}
  1. Hedef açılır listesinde bir iOS simülatörü seçin.
  2. Uygulamayı bir simülatörde çalıştırmak için Xcode'da CMD+R tuşlarına basın (veya Çalıştır düğmesini tıklayın).

4. Şemayı tanımlama ve veritabanını önceden doldurma

Bu bölümde, film uygulamasındaki temel öğeler arasındaki yapıyı ve ilişkileri bir şemada tanımlayacaksınız. Movie, MovieMetaData gibi öğeler, Firebase Data Connect ve GraphQL şema yönergeleri kullanılarak ilişkiler oluşturulmuş şekilde veritabanı tablolarına eşlenir.

Temel Varlıklar ve İlişkiler

Bu film izleme uygulamasının veri modeli, bu codelab boyunca oluşturacağınız çeşitli varlıklardan oluşur. Önce temel öğeleri oluşturacak, ardından daha fazla özellik uyguladıkça bu özellikler için gereken öğeleri ekleyeceksiniz.

Bu adımda Movie ve MovieMetadata türlerini oluşturacaksınız.

Film

Movie türü, title, genre, releaseYear ve rating gibi alanlar da dahil olmak üzere bir film öğesinin ana yapısını tanımlar.

VS Code'da Movie tür tanımını dataconnect/schema/schema.gql dosyasına ekleyin:

type Movie @table {
  id: UUID! @default(expr: "uuidV4()")
  title: String!
  imageUrl: String!
  releaseYear: Int
  genre: String
  rating: Float
  description: String
  tags: [String]
}

MovieMetadata

MovieMetadata türü, Movie türüyle bire bir ilişki kurar. Film yönetmeni gibi ek veriler içerir.

MovieMetadata tablo tanımını dataconnect/schema/schema.gql dosyasına ekleyin:

type MovieMetadata @table {
  movie: Movie! @ref
  director: String
}

Otomatik Oluşturulan Alanlar ve Varsayılanlar

Şema, benzersiz kimlikleri ve zaman damgalarını otomatik olarak oluşturmak için @default(expr: "uuidV4()") gibi ifadeler kullanır. Örneğin, Movie türündeki id alanı, yeni bir kayıt oluşturulduğunda otomatik olarak bir UUID ile doldurulur.

Filmler ve film meta verileri için sahte veriler ekleme

Şema tanımlandıktan sonra artık veritabanını test için sahte verilerle önceden doldurabilirsiniz.

  1. Finder'da finish/FriendlyFlix/dataconnect/moviedata_insert.gql dosyasını start/FriendlyFlix/dataconnect klasörüne kopyalayın.
  2. VS Code'da dataconnect/moviedata_insert.gql dosyasını açın.
  3. Firebase Data Connect uzantısındaki emülatörlerin çalıştığından emin olun.
  4. Dosyanın üst kısmında Run (local) [Çalıştır (yerel)] düğmesini görürsünüz. Sahte film verilerini veritabanınıza eklemek için bunu tıklayın.
  5. Verilerin başarıyla eklendiğini onaylamak için Data Connect Execution terminalini kontrol edin.

Veriler yerleştirildikten sonra, Data Connect'te nasıl sorgu oluşturacağınızı öğrenmek için bir sonraki adıma geçin.

5. Filmleri alma ve görüntüleme

Bu bölümde, film listesi görüntüleme özelliğini uygulayacaksınız.

İlk olarak, movies tablosundaki tüm filmleri alan bir sorgu oluşturmayı öğreneceksiniz. Firebase Data Connect, sorguyu yürütmek ve alınan filmleri uygulamanızın kullanıcı arayüzünde göstermek için kullanabileceğiniz tür güvenli bir SDK'nın kodunu oluşturur.

ListMovies sorgusunu tanımlayın

Firebase Data Connect'teki sorgular GraphQL ile yazılır. Bu sayede, hangi alanların getirileceğini belirleyebilirsiniz. FriendlyFlix'te filmlerin gösterildiği ekranlarda şu alanlar zorunludur: title, description, releaseYear, rating ve imageUrl. Ayrıca, bu bir SwiftUI uygulaması olduğundan SwiftUI görünüm kimliği konusunda yardımcı olması için id gerekir.

VS Code'da dataconnect/connector/queries.gql dosyasını açın ve ListMovies sorgusunu ekleyin:

query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    tags
    description
  }
}

Yeni sorguyu test etmek için Çalıştır (yerel) düğmesini tıklayarak sorguyu yerel veritabanınızda çalıştırın. Veritabanındaki filmlerin listesi, Data Connect Execution terminalinin Results (Sonuçlar) bölümünde gösterilmelidir.

ListMovies sorgusunu uygulamanın ana ekranına bağlayın

Veri Bağlantısı Emülatörü'nde sorguyu test ettiğinize göre artık sorguyu uygulamanızın içinden çağırabilirsiniz.

queries.gql kaydettiğinizde Firebase Data Connect, FriendlyFlixSDK paketinde ListMovies sorgusuna karşılık gelen kodu oluşturur.

Xcode'da Movie+DataConnect.swift dosyasını açın ve ListMoviesQuery.Data.Movie ile Movie arasında eşleme yapmak için aşağıdaki kodu ekleyin:

import FirebaseDataConnect
import FriendlyFlixSDK

extension Movie {
  init(from: ListMoviesQuery.Data.Movie) {
    id = from.id
    title = from.title
    description = from.description ?? ""
    releaseYear = from.releaseYear
    rating = from.rating
    imageUrl = from.imageUrl
  }
}

HomeScreen.swift dosyasını açın ve aşağıdaki kod snippet'ini kullanarak güncelleyin.

import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK

struct HomeScreen: View {
  ...

  private var connector = DataConnect.friendlyFlixConnector
  let heroMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>

  init() {
    heroMoviesRef = connector.listMoviesQuery.ref()
  }
}

extension HomeScreen {
  ...

  private var heroMovies: [Movie] {
    heroMoviesRef.data?.movies.map(Movie.init) ?? []
  }

 private var topMovies: [Movie] {
    heroMoviesRef.data?.movies.map(Movie.init) ?? []
  }

  private var watchList: [Movie] {
    heroMoviesRef.data?.movies.map(Movie.init) ?? []
  }

  ...
}

listMoviesQuery() sorgusu, queries.gql öğesini kaydettiğinizde Veri Bağlantısı tarafından oluşturulmuştur. Swift uygulamasını görmek için FriendlyFlixSDK paketindeki FriendlyFlixOperations.swift dosyasına göz atın.

Uygulamayı çalıştırma

Xcode'da, uygulamayı iOS Simülatörü'nde başlatmak için Çalıştır düğmesini tıklayın.

Uygulama başlatıldığında aşağıdaki gibi bir ekran görürsünüz:

Uygulamanın tüm alanlarında (ana bölüm, en popüler filmler ve izleme listesi) aynı listenin gösterildiğini fark edebilirsiniz. Bunun nedeni, tüm bu görünümler için aynı sorguyu kullanmanızdır. Sonraki bölümlerde özel sorgular uygulayacaksınız.

6. Öne çıkan öğe ve en iyi filmleri gösterme

Bu adımda, filmlerin ana ekrandaki üst kısımda yer alan önemli bantta ve altındaki en iyi filmler bölümünde gösterilme şeklini güncellemeye odaklanacaksınız.

Şu anda ListMovies sorgusu tüm filmleri alıyor. Bu bölümlerdeki gösterimi optimize etmek için her sorgunun döndürdüğü film sayısını sınırlayacaksınız. ListMovies sorgusunun mevcut uygulaması henüz sonuçları sınırlamak için yerleşik destek sunmuyor. Sınırlama ve sıralama desteği ekleme, bu bölümde yapacağınız bir işlemdir.

ListMovies sorgusunu geliştirme

queries.gql dosyasını açın ve sipariş ve sınırlama desteği eklemek için ListMovies dosyasını aşağıdaki gibi güncelleyin:

query ListMovies(
  $orderByRating: OrderDirection
  $orderByReleaseYear: OrderDirection
  $limit: Int
) @auth(level: PUBLIC) {
  movies(
    orderBy: [{ rating: $orderByRating }, { releaseYear: $orderByReleaseYear }]
    limit: $limit
  ) {
    id
    title
    description
    releaseYear
    rating
    imageUrl
  }
}

Bu sayede, sorgunun döndürdüğü film sayısını sınırlayabilir ve sonuç kümesini hem derecelendirmeye hem de yayınlanma yılına göre sıralayabilirsiniz.

Bu dosyayı kaydettikten sonra Firebase Data Connect, FriendlyFlixSDK içindeki kodu otomatik olarak yeniden oluşturur. Sonraki adımda, bu ek özelliklerden yararlanmak için HomeScreen.swift içindeki kodu güncelleyebilirsiniz.

Arayüzde gelişmiş sorguyu kullanma

HomeScreen.swift üzerinde gerekli değişiklikleri yapmak için Xcode'a geri dönün.

Öncelikle, en son yayınlanan 3 filmi getirmek için heroMoviesRef öğesini güncelleyin:

struct HomeScreen {
  ...

  init() {
    heroMoviesRef = connector.listMoviesQuery
      .ref { optionalVars in
        optionalVars.limit = 3
        optionalVars.orderByReleaseYear = .DESC
      }

  }
}

Ardından, en iyi filmler için başka bir sorgu referansı oluşturun ve filtreyi en yüksek puanlı 5 film olarak ayarlayın:

struct HomeScreen {
  ...

  let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>

  init() {
    heroMoviesRef = ...

    topMoviesRef = connector.listMoviesQuery
      .ref { optionalVars in
        optionalVars.limit = 5
        optionalVars.orderByRating = .DESC
      }
  }
}

Son olarak, bu sorgunun sonucunu kullanıcı arayüzüne bağlayan hesaplanmış özelliği güncelleyin:

extension HomeScreen {
  ...

  private var topMovies: [Movie] {
    topMoviesRef.data?.movies.map(Movie.init) ?? []
  }

}

Kullanım örnekleri

Ana sayfadaki son 3 filmi ve en çok beğenilen 5 filmi görmek için uygulamayı tekrar çalıştırın:

7. Film ve oyuncu ayrıntılarını görüntüleme

Kullanıcı artık filmlere göz atabilir. Bir film kartına dokunduklarında filmle ilgili bazı ayrıntılar gösterilir. Ancak bu ayrıntıların yeterince ayrıntılı olmadığını fark etmiş olabilirsiniz.

Bunun nedeni, film hero bölümünü ve en iyi filmler bölümünü oluşturmak için her film hakkında yalnızca film başlığı, kısa açıklama ve resim URL'si gibi gerekli bilgileri getirmemizdir.

Film ayrıntıları sayfasında filmle ilgili daha fazla bilgi göstermek istiyoruz. Bu bölümde, uygulamayı geliştirerek ayrıntılar sayfasında filmin oyuncularını ve yorumlarını gösterecek şekilde iyileştireceksiniz.

Bunun için yapmanız gerekenler:

  • Film oyuncularını ve yorumlarını desteklemek için şemayı geliştirme
  • Belirli bir filmle ilgili ayrıntıları getirmek için Firebase Data Connect sorguları yazma
  • Sonuçları film ayrıntıları ekranında gösterme

Şemayı geliştirme

VS Code'da dataconnect/schema/schema.gql dosyasını açın ve Actor ile MovieActor için şema tanımlarını ekleyin.

## Actors
## An actor can participate in multiple movies; movies can have multiple actors
## Movie - Actors (or vice versa) is a many to many relationship
type Actor @table {
  id: UUID!
  imageUrl: String!
  name: String! @col(name: "name", dataType: "varchar(30)")
}

## Join table for many-to-many relationship for movies and actors
## The 'key' param signifies the primary key(s) of this table
## In this case, the keys are [movieId, actorId], the generated fields of the reference types [movie, actor]
type MovieActor @table(key: ["movie", "actor"]) {
  ## @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
  ## In this case, @ref(fields: "id") is implied
  movie: Movie!
  ## movieId: UUID! <- this is created by the implied @ref, see: implicit.gql

  actor: Actor!
  ## actorId: UUID! <- this is created by the implied  @ref, see: implicit.gql

  role: String! ## "main" or "supporting"
}

Aktörler için sahte veriler ekleme

Şema güncellendiğinden artık veritabanını test için daha fazla sahte veriyle doldurabilirsiniz.

  1. Finder'da finish/FriendlyFlix/dataconnect/moviededetails_insert.gql dosyasını start/FriendlyFlix/dataconnect klasörüne kopyalayın.
  2. VS Code'da dataconnect/moviededetails_insert.gql dosyasını açın.
  3. Firebase Data Connect uzantısındaki emülatörlerin çalıştığından emin olun.
  4. Dosyanın üst kısmında Run (local) [Çalıştır (yerel)] düğmesini görürsünüz. Sahte film verilerini veritabanınıza eklemek için bunu tıklayın.
  5. Verilerin başarıyla eklendiğini onaylamak için Veri Bağlantısı Yürütme terminalini kontrol edin.

Veriler yerindeyken film ayrıntılarını getirecek sorguyu tanımlamak için bir sonraki adıma geçin.

GetMovieById sorgusunu tanımlayın

VS Code'da dataconnect/connector/queries.gql dosyasını açın ve GetMovieById sorgusunu ekleyin:

## Get movie by id
query GetMovieById($id: UUID!) @auth(level: PUBLIC) {
  movie(id: $id) {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    description
    tags
    metadata: movieMetadatas_on_movie {
      director
    }
    mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) {
      id
      name
      imageUrl
    }
    supportingActors: actors_via_MovieActor(
      where: { role: { eq: "supporting" } }
    ) {
      id
      name
      imageUrl
    }
  }
}

GetMovieById sorgusunu MovieDetailsView'a bağlayın.

Xcode'da MovieDetailsView.swift dosyasını açın ve movieDetails hesaplanmış özelliğini aşağıdaki kodla eşleşecek şekilde güncelleyin:

import NukeUI
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK

@MainActor
struct MovieDetailsView: View {
  private var movie: Movie

  private var movieDetails: MovieDetails? {
    DataConnect.friendlyFlixConnector
      .getMovieByIdQuery
      .ref(id: movie.id)
      .data?.movie.map { movieDetails in
        MovieDetails(
          title: movieDetails.title,
          description: movieDetails.description ?? "",
          releaseYear: movieDetails.releaseYear,
          rating: movieDetails.rating ?? 0,
          imageUrl: movieDetails.imageUrl,
          mainActors: movieDetails.mainActors.map { mainActor in
            MovieActor(id: mainActor.id,
                       name: mainActor.name,
                       imageUrl: mainActor.imageUrl)
          },
          supportingActors: movieDetails.supportingActors.map{ supportingActor in
            MovieActor(id: supportingActor.id,
                       name: supportingActor.name,
                       imageUrl: supportingActor.imageUrl)
          },
          reviews: []
        )
      }
  }

  public init(movie: Movie) {
    self.movie = movie
  }
}

Uygulamayı çalıştırma

Xcode'da, uygulamayı iOS Simülatörü'nde başlatmak için Çalıştır düğmesini tıklayın.

Uygulama başlatıldıktan sonra film ayrıntılarını görüntülemek için bir film kartına dokunun. Aşağıdaki gibi görünmelidir:

8. Kullanıcı kimlik doğrulamasını uygulama

Uygulama şu anda kişiselleştirilmemiş film ve aktör bilgileri sunmaktadır. Aşağıdaki adımlarda, verileri oturum açmış kullanıcıyla ilişkilendiren özellikleri uygulayacaksınız. Öncelikle kullanıcıların kişisel izleme listelerine film eklemesine izin vermeniz gerekir.

İzleme listesi özelliğini kullanabilmek için önce kullanıcı kimliğini oluşturmanız gerekir. Bunu etkinleştirmek için Firebase Authentication'ı entegre edersiniz. Böylece kullanıcılar uygulamada oturum açabilir.

Ana ekranın sağ üst kısmındaki kullanıcı avatarı düğmesini görmüş olabilirsiniz. Bu düğmeye dokunduğunuzda, kullanıcıların e-posta adreslerini ve şifrelerini kullanarak kaydolabileceği veya oturum açabileceği bir ekrana yönlendirilirsiniz.

Bir kullanıcı başarılı bir şekilde oturum açtıktan sonra uygulamanız, kullanıcının temel bilgilerini (öncelikle benzersiz kullanıcı kimliği ve seçilen kullanıcı adı) depolamalıdır.

Firebase Authentication'ı etkinleştirme

Projenizin Firebase konsolunda Authentication bölümüne gidin ve Firebase Authentication'ı etkinleştirin. Ardından, e-posta/şifre kimlik doğrulama sağlayıcısını etkinleştirin.

Yerel proje klasörünüzde firebase.json dosyasını bulun ve Firebase Authentication Emulator'ı etkinleştirmek için aşağıdaki şekilde güncelleyin.

{
  "emulators": {
    "dataconnect": {
    },
    "auth": {
    }
  },
  "dataconnect": {
    "source": "dataconnect"
  }
}

Bundan sonra, değişikliğin geçerli olması için Firebase Emulator'ı durdurup yeniden başlatmanız gerekir.

Kimlik doğrulama işleyicisi uygulama

Aşağıdaki bölümde, kullanıcı kimlik doğrulamasını veritabanınıza bağlayan mantığı uygulayacaksınız. Bu işlem, başarılı oturum açma işlemlerini dinleyen bir kimlik doğrulama işleyicisi oluşturmayı içerir.

Bir kullanıcı kimliği doğrulandıktan sonra bu işleyici, veritabanınızda kullanıcının ilgili hesabının oluşturulmasını otomatik olarak tetikler.

Xcode'da AuthenticationService.swift dosyasını açın ve aşağıdaki kodu ekleyin:

import Foundation
import Observation
import os
import FirebaseAuth

enum AuthenticationState {
  case unauthenticated
  case authenticating
  case authenticated
}

@Observable
class AuthenticationService {
  private let logger = Logger(subsystem: "FriendlyFlix", category: "auth")

  var presentingAuthenticationDialog = false
  var presentingAccountDialog = false

  var authenticationState: AuthenticationState = .unauthenticated
  var user: User?
  private var authenticationListener: AuthStateDidChangeListenerHandle?

  init() {
    authenticationListener = Auth.auth().addStateDidChangeListener { auth, user in
      if let user {
        self.authenticationState = .authenticated
        self.user = user
      } else {
        self.authenticationState = .unauthenticated
      }
    }
  }

  private var onSignUp: ((User) -> Void)?
  public func onSignUp(_ action: @escaping (User) -> Void) {
    onSignUp = action
  }

  func signInWithEmailPassword(email: String, password: String) async throws {
    try await Auth.auth().signIn(withEmail: email, password: password)
    authenticationState = .authenticated
  }

  func signUpWithEmailPassword(email: String, password: String) async throws {
    try await Auth.auth().createUser(withEmail: email, password: password)

    if let onSignUp, let user = Auth.auth().currentUser {
      logger
        .debug(
          "User signed in \(user.displayName ?? "(no fullname)") with email \(user.email ?? "(no email)")"
        )
      onSignUp(user)
    }

    authenticationState = .authenticated
  }

  func signOut() throws {
    try Auth.auth().signOut()
    authenticationState = .unauthenticated
  }
}

Bu, kullanıcının oturum açtığında çağrılacak bir kapatma kaydetmenize olanak tanıyan genel bir kimlik doğrulama işleyicisidir.onSignUp

Bu kapatma işlemi içinde veritabanında yeni bir kullanıcı hesabı oluşturabilirsiniz. Ancak bunu yapabilmeniz için veritabanında yeni kullanıcılar oluşturmanıza veya mevcut kullanıcıları güncellemenize olanak tanıyan bir mutasyon oluşturmanız gerekir.

Şemaya bir Kullanıcı varlığı ekleme

User türü, bir kullanıcı öğesini tanımlar. Kullanıcılar, yorum bırakarak veya filmleri favorilerine ekleyerek filmlerle etkileşim kurabilir.

VS Code'da dataconnect/schema/schema.gql dosyasını açın ve aşağıdaki User tablo tanımını ekleyin:

## Users
## A user can leave reviews for movies
## user-reviews is a one to many relationship, movie-reviews is a one to many relationship, movie:user is a many to many relationship
type User @table {
  id: String! @col(name: "user_auth")
  username: String! @col(name: "username", dataType: "varchar(50)")
}

Kullanıcı ekleme veya güncelleme için bir mutasyon tanımlayın

VS Code'da dataconnect/connector/mutations.gql dosyasını açın ve UpsertUser mutasyonunu ekleyin:

mutation UpsertUser($username: String!) @auth(level: USER) {
  user_upsert(
    data: {
      id_expr: "auth.uid"
      username: $username
    }
  )
}

Başarıyla giriş yaptıktan sonra yeni bir kullanıcı oluşturma

Xcode'da FriendlyFlixApp.swift dosyasını açın ve başlatıcıya aşağıdaki kodu ekleyin:

@main
struct FriendlyFlixApp: App {

  ...

  init() {
    ...
    authenticationService = AuthenticationService()
    authenticationService?.onSignUp { user in
      let userName = String(user.email?.split(separator: "@").first ?? "(unknown)")
      Task {
        try await DataConnect.friendlyFlixConnector
          .upsertUserMutation.execute(username: userName)
      }
    }
  }

  var body: some Scene {
    ...
  }
}

Bu kod, Firebase Authentication kullanılarak başarılı bir şekilde kaydolan her kullanıcı için yeni bir kullanıcı eklemek (veya aynı kimliğe sahip mevcut bir kullanıcıyı güncellemek) üzere sizin için oluşturulan upsertUserMutation Firebase Data Connect'i kullanır.

Kullanım örnekleri

Bu özelliğin çalıştığını doğrulamak için önce iOS uygulamasında kaydolun:

  • Henüz yapmadıysanız Firebase Authentication Emulator'ın çalıştığından emin olmak için Firebase Emulator'ı durdurup yeniden başlatın.
  • Xcode'da, uygulamayı iOS Simülatörü'nde başlatmak için Çalıştır düğmesini tıklayın.
  • Ekranın sağ üst köşesindeki avatar simgesini tıklayın.
  • Kaydolma akışına geçin ve uygulamaya kaydolun.

Ardından, uygulamanın kullanıcı için yeni bir kullanıcı hesabı oluşturduğunu doğrulamak üzere veritabanını sorgulayın:

  • VS Code'da dataconnect/schema/schema.gql dosyasını açın ve User öğesinde Verileri oku'yu tıklayın.
  • Bu işlem, User_read.gql adlı yeni bir sorgu dosyası oluşturur.
  • Kullanıcı tablosundaki tüm kullanıcıları görmek için Yerel olarak çalıştır'ı tıklayın.
  • Veri Bağlantısı Yürütme bölmesinde, yeni kaydettiğiniz kullanıcı için bir hesap görmeniz gerekir

9. Favori filmleri yönetme

Bu codelab bölümünde, film inceleme uygulamasında kullanıcı etkileşimlerini uygulayacaksınız. Özellikle kullanıcıların favori filmlerini yönetmesine izin vereceksiniz. Favori olarak işaretlenen filmler, uygulamanın izleme listesi bölümünde gösterilir.

Favorileri desteklemek için şemayı geliştirin

FavoriteMovie türü, kullanıcılar ve en sevdikleri filmler arasındaki çoktan çoka ilişkileri işleyen bir birleştirme tablosudur. Her tablo, bir User ile bir Movie'yi birbirine bağlar.

Kod snippet'ini kopyalayıp dataconnect/schema/schema.gql dosyanıza yapıştırın:

type FavoriteMovie
  @table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
  ## @ref is implicit
  user: User!
  movie: Movie!
}

Favori ekleme ve kaldırma için mutasyonları tanımlayın

Uygulamanın kullanıcının favori filmlerini gösterebilmesi için kullanıcının hangi filmlerin favorisi olduğunu belirtmesi gerekir. Bunu yapmak için önce iki mutasyon ekleyerek bir filmi kullanıcının favorileri arasına eklemeniz veya favorilerinden kaldırmanız gerekir.

  1. VS Code'da mutations.gql dosyasını dataconnect/connector/mutations.gql içinde açın.
  2. Filmleri favorilere ekleme işlemini gerçekleştirmek için aşağıdaki mutasyonları ekleyin:
## Add a movie to the user's favorites list
mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId })
}

## Remove a movie from the user's favorites list
mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}

Mutasyonları uygulamanızın kullanıcı arayüzüne bağlama

Kullanıcılar, filmin ayrıntılar ekranındaki kalp simgesini tıklayarak filmi favorilerine ekleyebilir.

Yeni oluşturduğunuz mutasyonları uygulamanın kullanıcı arayüzüne bağlamak için MovieCardView içinde aşağıdaki değişiklikleri yapın:

  1. FriendlyFlixSDK dosyasını içe aktarın ve bağlayıcıyı ayarlayın
import NukeUI
import os
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK

struct MovieCardView: View {
  private let logger = Logger(subsystem: "FriendlyFlix", category: "moviecard")
  @Environment(\.dismiss) private var dismiss
  private var connector = DataConnect.friendlyFlixConnector

  ...
}
  1. toggleFavourite yöntemini uygulayın. Kullanıcı MovieCardView bölümünde kalp simgesine dokunduğunda çağrılır:
struct MovieCardView {

  ...

  private func toggleFavourite() {
    Task {
      if isFavourite {
        let _ = try await connector.deleteFavoritedMovieMutation.execute(movieId: movie.id)
      } else {
        let _ = try await connector.addFavoritedMovieMutation.execute(movieId: movie.id)
      }
    }
  }
}

Bu işlem, veritabanındaki mevcut filmin favori durumunu günceller. Eksik olan son adım, kullanıcı arayüzü durumunun buna göre yansıtıldığından emin olmaktır.

Bir filmin favori olarak işaretlenip işaretlenmediğini belirlemek için sorgu tanımlama

  1. VS Code'da queries.gql dosyasını dataconnect/connector içinde açın.
  2. Bir filmin favori olarak işaretlenip işaretlenmediğini kontrol etmek için aşağıdaki sorguyu ekleyin:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
    movieId
  }
}
  1. Xcode'da GetIfFavoritedMovie sorgusuna bir referans oluşturun ve bu MovieCardView üzerinde gösterilen filmin mevcut kullanıcı için favori olarak işaretlenip işaretlenmediğini belirleyen hesaplanmış özelliği uygulayın.
struct MovieCardView: View {

  ...

  public init(showDetails: Bool, movie: Movie) {
    self.showDetails = showDetails
    self.movie = movie

    isFavouriteRef = connector.getIfFavoritedMovieQuery.ref(movieId: movie.id)
  }

  // MARK: - Favourite handling

  private let isFavouriteRef: QueryRefObservation<
    GetIfFavoritedMovieQuery.Data,
    GetIfFavoritedMovieQuery.Variables
  >
  private var isFavourite: Bool {
    isFavouriteRef.data?.favorite_movie?.movieId != nil
  }

  ...

}
  1. Kullanıcı düğmeye her dokunduğunda sorguyu yürütmek için toggleFavourite içindeki kodu güncelleyin. Bu sayede isFavourite hesaplanmış özelliği her zaman doğru değeri döndürür.
  private func toggleFavourite() {
    Task {
      if isFavourite {
        ...
      }

      let _ = try await isFavouriteRef.execute()
    }
  }

Favori filmleri getirme

Bu özelliğin son adımı olarak, kullanıcının favori filmlerini getirme işlevini uygulayacaksınız. Böylece kullanıcılar bu filmleri izleme listelerinde görebilecek.

  1. VS Code'da queries.gql dosyasını dataconnect/connector/queries.gql içinde açın ve aşağıdaki sorguyu yapıştırın:
## Get favorite movies by user ID
query GetUserFavoriteMovies @auth(level: USER) {
  user(id_expr: "auth.uid") {
    favoriteMovies: favorite_movies_on_user {
      movie {
        id
        title
        genre
        imageUrl
        releaseYear
        rating
        description
      }
    }
  }
}

Kullanıcının favori filmler listesi LibraryScreen üzerinde gösterilir. Bu ekran yalnızca kullanıcı oturum açmışsa verileri göstermelidir. Bu nedenle, önce ekranın kimlik doğrulama durumunu uygulamanın AuthenticationService ile bağlarsınız.

  1. FavoriteMovieFavoriteMovies'dan Movie'a ve Movie+DataConnect.swift'ya giden rotanın haritasına kod ekleme:
import FirebaseDataConnect
import FriendlyFlixSDK

extension Movie {

  ...

  init(from: GetUserFavoriteMoviesQuery.Data.User.FavoriteMovieFavoriteMovies) {
    id = from.movie.id
    title = from.movie.title
    description = from.movie.description ?? ""
    releaseYear = from.movie.releaseYear
    rating = from.movie.rating
    imageUrl = from.movie.imageUrl
  }
}
  1. Xcode'da LibraryScreen dosyasını açın ve isSignedIn dosyasını aşağıdaki şekilde güncelleyin:
struct LibraryScreen: View {
  ...

  private var isSignedIn: Bool {
    authenticationService.user != nil
  }

}
  1. Ardından Firebase Data Connect ve FriendlyFlixSDK'yı içe aktarın ve GetUserFavoriteMovies sorgusuna referans alın:
import SwiftUI
import FirebaseDataConnect
import FriendlyFlixSDK

struct LibraryScreen {

 ...

  private var connector = DataConnect.friendlyFlixConnector

  ...

  init() {
    watchListRef = connector.getUserFavoriteMoviesQuery.ref()
  }

  private let watchListRef: QueryRefObservation<
    GetUserFavoriteMoviesQuery.Data,
    GetUserFavoriteMoviesQuery.Variables
  >
  private var watchList: [Movie] {
    watchListRef.data?.user?.favoriteMovies.map(Movie.init) ?? []
  }

  ...

}


  1. Görünüm göründüğünde watchListRef sorgusunun yürütüldüğünden emin olun:
extension LibraryScreen: View {
  var body: some View {
    ...
            MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
              .onAppear {
                Task {
                  try await watchListRef.execute()
                }
  ...

Kullanım örnekleri

Artık uygulamayı çalıştırabilir ve yeni uyguladığınız favoriler özelliğini deneyebilirsiniz. Unutulmaması gereken birkaç nokta:

  • Firebase emülatörünün çalıştığından emin olun
  • Filmler ve film ayrıntıları için sahte veriler eklediğinizden emin olun.
  • Kullanıcı olarak kaydolduğunuzdan emin olun
  1. Xcode'da, uygulamayı iOS Simülatörü'nde başlatmak için Çalıştır düğmesini tıklayın.
  2. Uygulama başlatıldıktan sonra film ayrıntılarını görüntülemek için bir film kartına dokunun.
  3. Filmi favori olarak işaretlemek için kalp simgesine dokunun. Kalp simgesi dolu görünür.
  4. Bu işlemi birkaç film için tekrarlayın.
  5. Kitaplık sekmesine gidin. Artık favori olarak işaretlediğiniz tüm filmlerin listesini görebilirsiniz.

10. Tebrikler

Tebrikler, Firebase Data Connect'i bir iOS uygulamasına başarıyla eklediniz. Artık Veri Bağlantısı'nı ayarlamak, sorgular ve mutasyonlar oluşturmak ve kullanıcı kimlik doğrulamasını işlemek için gereken temel adımları biliyorsunuz.

İsteğe bağlı: Üretime dağıtma

Bu uygulama şu ana kadar yalnızca Firebase Emulator'larını kullandı. Bu uygulamayı gerçek bir Firebase projesine nasıl dağıtacağınızı öğrenmek istiyorsanız bir sonraki adıma geçin.

11. (İsteğe bağlı) Uygulamanızı dağıtın

Bu uygulama şu ana kadar tamamen yereldi ve tüm veriler Firebase Emulator Suite'te yer alıyordu. Bu bölümde, Firebase projenizi bu uygulamanın üretimde çalışacak şekilde nasıl yapılandıracağınızı öğreneceksiniz.

Firebase Authentication'ı etkinleştirme

  1. Firebase konsolunda Kimlik Doğrulama bölümüne gidin ve Başlayın'ı tıklayın.
  2. Oturum açma yöntemi sekmesine gidin .
  3. Yerel sağlayıcılar bölümünden E-posta/Şifre seçeneğini belirleyin.
  4. E-posta/Şifre sağlayıcısını etkinleştirin ve Kaydet'i tıklayın.

Firebase Data Connect'i etkinleştirme

Önemli: Projenizde ilk kez şema dağıtıyorsanız bu işlem, yaklaşık 15 dakika sürebilen bir Cloud SQL PostgreSQL örneği oluşturur. Cloud SQL örneği hazır olana ve Firebase Data Connect ile entegre edilene kadar dağıtım yapamazsınız.

1. Firebase Data Connect VS Code uzantısı kullanıcı arayüzünde Üretime dağıt'ı tıklayın. 2. Şema değişikliklerini incelemeniz ve potansiyel olarak yıkıcı olabilecek değişiklikleri onaylamanız gerekebilir. Şunları yapmanız istenir: - firebase dataconnect:sql:diff kullanarak şema değişikliklerini inceleyin. - Değişikliklerden memnun olduğunuzda firebase dataconnect:sql:migrate tarafından başlatılan akışı kullanarak değişiklikleri uygulayın.

PostgreSQL için Cloud SQL örneğiniz, son dağıtılan şema ve verilerle güncellenir. Durumu Firebase konsolunda izleyebilirsiniz.

Artık üretim ortamına veri eklemek için Firebase Data Connect panelinde yerel emülatörlerde yaptığınız gibi Çalıştır (Üretim) seçeneğini tıklayabilirsiniz.

iOS uygulamasını tekrar çalıştırmadan önce projenizin üretim örneğine bağlandığından emin olun:

  1. Product (Ürün) > Scheme (Şema) > Edit Scheme (Şemayı Düzenle)... menüsünü açın.
  2. Run (Çalıştır) bölümünde -useEmulator YES başlatma bağımsız değişkeninin işaretini kaldırın.