1. بررسی اجمالی
این کد لبه شما را در فرآیند ادغام Firebase Data Connect با پایگاه داده Cloud SQL برای ساختن یک برنامه بررسی فیلم برای iOS با استفاده از SwiftUI راهنمایی می کند.
شما یاد خواهید گرفت که چگونه برنامه iOS خود را با استفاده از Firebase Data Connect به یک پایگاه داده Cloud SQL متصل کنید و همگام سازی یکپارچه داده ها را برای بررسی فیلم ها ممکن می کند.
در پایان این کد لبه، شما یک برنامه کاربردی iOS خواهید داشت که به کاربران امکان می دهد فیلم ها را مرور کنند و فیلم ها را به عنوان موارد دلخواه علامت گذاری کنند، که همگی توسط یک پایگاه داده Cloud SQL با استفاده از قدرت Firebase Data Connect پشتیبانی می شوند.
چیزی که یاد خواهید گرفت
این کد لبه به شما یاد می دهد که چگونه:
- Firebase Data Connect را با استفاده از مجموعه Firebase Emulator برای دور زدن سریع راه اندازی کنید .
- طرحی از پایگاه داده با استفاده از Data Connect و GraphQL طراحی کنید.
- یک Typesafe Swift SDK از طرح پایگاه داده خود ایجاد کنید و آن را به یک برنامه Swift اضافه کنید.
- احراز هویت کاربر را پیاده سازی کنید و آن را با Firebase Data Connect ادغام کنید تا داده های کاربران خود را ایمن کنید.
- بازیابی، به روز رسانی، حذف و مدیریت داده ها در Cloud SQL با استفاده از پرس و جوها و جهش های ارائه شده توسط GraphQL.
- (اختیاری) یک سرویس Data Connect را برای تولید مستقر کنید .
پیش نیازها
- آخرین نسخه Xcode
- کد نمونه کد لبه. نمونه کد را در یکی از اولین مراحل نرم افزار Codelab دانلود خواهید کرد.
2. پروژه نمونه را راه اندازی کنید
یک پروژه Firebase ایجاد کنید
- با حساب Google خود وارد کنسول Firebase شوید.
- در کنسول Firebase ، روی ایجاد پروژه Firebase کلیک کنید.
- نامی برای پروژه Firebase خود وارد کنید (به عنوان مثال، "Friendly Flix") و روی Continue کلیک کنید.
- ممکن است از شما خواسته شود که کمک هوش مصنوعی را برای پروژه Firebase خود فعال کنید. برای هدف این نرم افزار کد، انتخاب شما مهم نیست.
- ممکن است از شما خواسته شود که Google Analytics را فعال کنید. برای اهداف این نرم افزار کد، انتخاب شما مهم نیست.
- پس از یک دقیقه یا بیشتر، پروژه Firebase شما آماده خواهد شد. روی Continue کلیک کنید.
کد را دانلود کنید
دستور زیر را برای کلون کردن کد نمونه برای این Codelab اجرا کنید. این یک دایرکتوری به نام codelab-dataconnect-ios
در دستگاه شما ایجاد می کند:
git clone https://github.com/FirebaseExtended/codelab-dataconnect-ios`
اگر git روی دستگاه خود ندارید، می توانید کد را مستقیماً از GitHub نیز دانلود کنید.
پیکربندی Firebase را اضافه کنید
Firebase SDK از یک فایل پیکربندی برای اتصال به پروژه Firebase شما استفاده می کند. در پلتفرمهای اپل، این فایل GoogleServices-Info.plist
نام دارد. در این مرحله فایل پیکربندی را دانلود کرده و به پروژه Xcode خود اضافه می کنید.
- در کنسول Firebase ، نمای کلی پروژه را در ناوبری سمت چپ انتخاب کنید.
- برای انتخاب پلتفرم، روی دکمه iOS+ کلیک کنید. وقتی از اپل باندل آیدی خواسته شد، از
com.google.firebase.samples.FriendlyFlix
استفاده کنید - روی ثبت برنامه کلیک کنید و دستورالعمل ها را برای دانلود فایل
GoogleServices-Info.plist
دنبال کنید. - فایل دانلود شده را به دایرکتوری
start/FriendlyFlix/app/FriendlyFlix/FriendlyFlix/
کدی که هماکنون دانلود کردهاید، منتقل کنید و جایگزین فایلGoogleServices-Info.plist
موجود کنید. - سپس چند بار روی Next کلیک کنید تا پروژه راهاندازی در کنسول Firebase کامل شود (نیازی نیست SDK را به برنامه اضافه کنید، زیرا قبلاً در پروژه شروع کننده برای شما مراقبت شده است).
- در نهایت روی Continue to console کلیک کنید تا مراحل نصب به پایان برسد.
3. Data Connect را راه اندازی کنید
نصب و راه اندازی
نصب خودکار
دستور زیر را در پوشه codelab-dataconnect-ios/FriendlyFlix
اجرا کنید:
curl -sL https://firebase.tools/dataconnect | bash
این اسکریپت سعی می کند محیط توسعه را برای شما تنظیم کند و یک IDE مبتنی بر مرورگر راه اندازی کند. این IDE ابزارهایی از جمله یک پسوند کد VS از پیش همراه را ارائه می دهد تا به شما کمک کند طرحواره خود را مدیریت کنید و پرس و جوها و جهش هایی را برای استفاده در برنامه خود تعریف کنید و SDK هایی با تایپ قوی ایجاد کنید.
پس از اجرای اسکریپت، VS Code باید به طور خودکار باز شود.
بعد از اینکه یک بار این کار را انجام دادید، می توانید VS Code را با اجرای VS Code در فهرست محلی راه اندازی کنید:
code .
نصب دستی
- کد ویژوال استودیو را نصب کنید
- Node.js را نصب کنید
- در VS Code، پوشه
codelab-dataconnect-ios/FriendlyFlix
را باز کنید. - افزونه Firebase Data Connect را از Visual Studio Code Marketplace نصب کنید.
Data Connect را در پروژه راه اندازی کنید
در پانل سمت چپ، روی نماد Firebase کلیک کنید تا رابط کاربری افزونه Data Connect VS Code باز شود
- روی دکمه Sign in with Google کلیک کنید. یک پنجره مرورگر باز می شود؛ دستورالعمل ها را دنبال کنید تا با حساب Google خود به برنامه افزودنی وارد شوید.
- روی دکمه Connect a Firebase project کلیک کنید و پروژه ای را که قبلا در کنسول ایجاد کردید انتخاب کنید.
- روی دکمه Run firebase init کلیک کنید و مراحل موجود در ترمینال یکپارچه را دنبال کنید.
پیکربندی تولید SDK
هنگامی که روی دکمه Run firebase init کلیک کردید، پسوند Firebase Data Connect باید یک پوشه dataconnect
را برای شما مقداردهی اولیه کند.
در VS Code فایل dataconnect/connector/connector.yaml
را باز کنید و پیکربندی پیش فرض را پیدا خواهید کرد.
لطفاً پیکربندی را بهروزرسانی کنید و از تنظیمات زیر استفاده کنید تا مطمئن شوید کد تولید شده با این کد لبه کار میکند. به طور خاص، مطمئن شوید که connectorId
روی friendly-flix
و بسته Swift روی FriendlyFlixSDK
تنظیم شده باشد.
connectorId: "friendly-flix"
generate:
swiftSdk:
outputDir: "../../app"
package: "FriendlyFlixSDK"
observablePublisher: observableMacro
این تنظیمات به چه معناست:
-
connectorId
- یک نام منحصر به فرد برای این رابط. -
outputDir
- مسیری که Data Connect SDK تولید شده در آن ذخیره خواهد شد. این مسیر نسبت به دایرکتوری حاوی فایلconnector.yaml
است. -
package
- نام بسته مورد استفاده برای بسته Swift تولید شده.
هنگامی که این فایل را ذخیره کردید، Firebase Data Connect یک بسته سوئیفت به نام FriendlyFlixSDK
برای شما تولید می کند و آن را در کنار پوشه پروژه FriendlyFlix
قرار می دهد.
شبیه سازهای Firebase را راه اندازی کنید
در VS Code، به نمای Firebase بروید و سپس روی دکمه Start emulators کلیک کنید.
با این کار شبیه ساز Firebase در ترمینال یکپارچه راه اندازی می شود. خروجی باید به شکل زیر باشد:
npx -y firebase-tools@latest emulators:start --project <your-project-id>
بسته ایجاد شده را به برنامه سوئیفت خود اضافه کنید
-
FriendlyFlix/app/FriendlyFlix/FriendlyFlix.xcodeproj
را در Xcode باز کنید - File > Add Package Dependencies را انتخاب کنید...
- روی Add Local... کلیک کنید، سپس بسته
FriendlyFlixSDK
را از پوشهFriendlyFlix/app
اضافه کنید. - منتظر بمانید تا Xcode وابستگی های بسته را برطرف کند.
- در گفتگوی Choose Package Products for FriendlyFlixSDK ،
FriendlyFlix
به عنوان هدف انتخاب کنید و روی Add Package کلیک کنید.
برنامه iOS را برای استفاده از شبیه ساز محلی پیکربندی کنید
-
FriendlyFlixApp.swift
را باز کنید. (می توانید CMD + Shift + O را فشار دهید تا پنجره باز کردن سریع باز شود و سپس «FriendlyFlixApp» را تایپ کنید تا فایل را سریع پیدا کنید) - Firebase، Firebase Auth، Firebase Data Connect و SDK ایجاد شده را برای طرح شما وارد کنید
- در آغازگر، Firebase را پیکربندی کنید.
- اطمینان حاصل کنید که DataConnect و Firebase Auth از شبیه ساز محلی استفاده می کنند.
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()
}
...
}
- یک شبیه ساز iOS را در منوی کشویی Destination انتخاب کنید.
- CMD+R را فشار دهید (یا روی دکمه Run کلیک کنید) در Xcode برای اجرای برنامه در شبیه ساز.
4. طرحواره را تعریف کرده و پایگاه داده را از قبل پر کنید
در این بخش، ساختار و روابط بین موجودیت های کلیدی در برنامه فیلم را در یک طرحواره تعریف می کنید. موجودیتهایی مانند Movie
، MovieMetaData
و موارد دیگر در جداول پایگاه داده نگاشت میشوند، با روابطی که با استفاده از Firebase Data Connect و دستورالعملهای طرحواره GraphQL ایجاد میشوند.
نهادهای اصلی و روابط
مدل داده این برنامه ردیاب فیلم از چندین موجودیت تشکیل شده است که در طول این برنامه کد ایجاد خواهید کرد. ابتدا موجودیتهای اصلی را ایجاد میکنید، و - با پیادهسازی ویژگیهای بیشتر و بیشتر - موجودیتهای مورد نیاز برای آن ویژگیها را اضافه میکنید.
در این مرحله انواع Movie
و MovieMetadata
را ایجاد می کنید.
فیلم
نوع Movie
ساختار اصلی یک موجودیت فیلم را شامل فیلدهایی مانند title
، genre
، releaseYear
و rating
تعریف می کند.
در VS Code، تعریف نوع Movie
را به dataconnect/schema/schema.gql
اضافه کنید:
type Movie @table {
id: UUID! @default(expr: "uuidV4()")
title: String!
imageUrl: String!
releaseYear: Int
genre: String
rating: Float
description: String
tags: [String]
}
MovieMetadata
نوع MovieMetadata
یک رابطه یک به یک با نوع Movie
برقرار می کند. این شامل اطلاعات اضافی مانند کارگردان فیلم است.
تعریف جدول MovieMetadata
را به فایل dataconnect/schema/schema.gql
اضافه کنید:
type MovieMetadata @table {
movie: Movie! @ref
director: String
}
فیلدها و پیش فرض های تولید شده به صورت خودکار
این طرح از عباراتی مانند @default(expr: "uuidV4()")
برای تولید خودکار شناسه ها و مُهرهای زمانی منحصر به فرد استفاده می کند. به عنوان مثال، فیلد id
در نوع Movie
به طور خودکار با یک UUID پر می شود که یک رکورد جدید ایجاد شود.
داده های ساختگی را برای فیلم ها و ابرداده های فیلم درج کنید
با طرح تعریف شده، اکنون می توانید پایگاه داده را با داده های ساختگی برای آزمایش از قبل پر کنید.
- در Finder،
finish/FriendlyFlix/dataconnect/moviedata_insert.gql
در پوشهstart/FriendlyFlix/dataconnect
کپی کنید. - در VS Code،
dataconnect/moviedata_insert.gql
باز کنید. - اطمینان حاصل کنید که شبیه سازها در افزونه Firebase Data Connect در حال اجرا هستند.
- شما باید یک دکمه Run (محلی) را در بالای فایل ببینید. روی این کلیک کنید تا داده های فیلم ساختگی را در پایگاه داده خود وارد کنید.
- پایانه اجرای Data Connect Execution را بررسی کنید تا تأیید کنید که داده ها با موفقیت اضافه شده اند.
با دادههای موجود، به مرحله بعدی بروید تا نحوه ایجاد پرس و جو در Data Connect را بیاموزید.
5. بازیابی و نمایش فیلم ها
در این قسمت قابلیت نمایش لیست فیلم ها را پیاده سازی خواهید کرد.
ابتدا یاد می گیرید که چگونه یک پرس و جو ایجاد کنید که همه فیلم ها را از جدول movies
بازیابی کند. Firebase Data Connect کدی را برای یک Typesafe SDK تولید می کند که سپس می توانید از آن برای اجرای پرس و جو و نمایش فیلم های بازیابی شده در رابط کاربری برنامه خود استفاده کنید.
کوئری ListMovies را تعریف کنید
کوئری ها در Firebase Data Connect در GraphQL نوشته می شوند و به شما امکان می دهند تعیین کنید کدام فیلدها را واکشی کنید. در FriendlyFlix، صفحههایی که فیلمها را نمایش میدهند به فیلدهای زیر نیاز دارند: title
، description
، releaseYear
، rating
و imageUrl
. علاوه بر این، از آنجایی که این یک برنامه SwiftUI است، برای کمک به شناسایی هویت SwiftUI به id
نیاز دارید.
در VS Code، فایل dataconnect/connector/queries.gql
را باز کنید و کوئری ListMovies
اضافه کنید:
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
releaseYear
genre
rating
tags
description
}
}
برای آزمایش کوئری جدید، روی دکمه Run (محلی) کلیک کنید تا پرس و جو در پایگاه داده محلی شما اجرا شود. فهرست فیلمهای پایگاه داده باید در قسمت Results ترمینال Data Connect Execution نمایش داده شود.
درخواست ListMovies را به صفحه اصلی برنامه متصل کنید
اکنون که پرس و جو را در شبیه ساز Data Connect آزمایش کرده اید، می توانید درخواست را از داخل برنامه خود فراخوانی کنید.
هنگامی که queries.gql
ذخیره می کنید، Firebase Data Connect کد مربوط به جستجوی ListMovies
را در بسته FriendlyFlixSDK
ایجاد می کند.
در Xcode، Movie+DataConnect.swift
را باز کنید و کد زیر را به نقشه از ListMoviesQuery.Data.Movie
به Movie
اضافه کنید:
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
را باز کرده و با استفاده از قطعه کد زیر آن را به روز کنید.
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) ?? []
}
...
}
زمانی که |
برنامه را اجرا کنید
در Xcode، روی دکمه Run کلیک کنید تا برنامه در شبیه ساز iOS راه اندازی شود.
پس از راهاندازی برنامه، باید صفحهای به شکل زیر مشاهده کنید:
ممکن است متوجه شوید که همه قسمتهای برنامه (بخش قهرمان، فیلمهای برتر و فهرست تماشا) یک لیست را نشان میدهند. این به این دلیل است که شما از یک پرس و جو برای همه آن نماها استفاده می کنید. در بخش های بعدی، کوئری های سفارشی را پیاده سازی خواهید کرد. |
6. نمایش فیلم های قهرمان و برتر
در این مرحله، روی بهروزرسانی نحوه نمایش فیلمها در بخش قهرمان تمرکز خواهید کرد - این چرخ فلک برجسته در بالای صفحه اصلی است - و همچنین در بخش فیلمهای برتر زیر.
در حال حاضر، جستجوی ListMovies همه فیلمها را بازیابی میکند. برای بهینهسازی نمایش برای این بخشها، تعداد فیلمهایی را که هر پرس و جو برمیگرداند محدود میکنید. اجرای فعلی جستجوی ListMovies
هنوز پشتیبانی داخلی برای محدود کردن نتایج ارائه نمی دهد - اضافه کردن پشتیبانی برای محدود کردن و سفارش دادن چیزی است که در این بخش اضافه خواهید کرد.
کوئری ListMovies را تقویت کنید
queries.gql
را باز کنید و ListMovies
به صورت زیر به روز کنید تا پشتیبانی برای سفارش و محدود کردن اضافه کنید:
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
}
}
این به شما این امکان را میدهد که تعداد فیلمهایی را که درخواست بازگردانده میشود محدود کنید و نتایج تنظیمشده بر اساس رتبهبندی و سال انتشار را سفارش دهید.
هنگامی که این فایل را ذخیره کردید، Firebase Data Connect به طور خودکار کد را در FriendlyFlixSDK
دوباره تولید می کند. در مرحله بعد، میتوانید کد را در HomeScreen.swift
بهروزرسانی کنید تا از این ویژگیهای اضافی استفاده کنید.
از کوئری پیشرفته در UI استفاده کنید
برای انجام تغییرات لازم در HomeScreen.swift
به Xcode برگردید.
ابتدا heroMoviesRef
را به روز کنید تا 3 فیلم اخیراً منتشر شده را دریافت کنید:
struct HomeScreen {
...
init() {
heroMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 3
optionalVars.orderByReleaseYear = .DESC
}
}
}
سپس، یک مرجع جستجوی دیگر را برای فیلمهای برتر تنظیم کنید و فیلتر را روی 5 فیلم با بالاترین امتیاز تنظیم کنید:
struct HomeScreen {
...
let topMoviesRef: QueryRefObservation<ListMoviesQuery.Data, ListMoviesQuery.Variables>
init() {
heroMoviesRef = ...
topMoviesRef = connector.listMoviesQuery
.ref { optionalVars in
optionalVars.limit = 5
optionalVars.orderByRating = .DESC
}
}
}
در نهایت، ویژگی محاسبه شده را که نتیجه این کوئری را به UI متصل می کند، به روز کنید:
extension HomeScreen {
...
private var topMovies: [Movie] {
topMoviesRef.data?.movies.map(Movie.init) ?? []
}
}
آن را در عمل ببینید
برای دیدن 3 فیلم اخیر در بخش قهرمان و 5 فیلم با بالاترین امتیاز در بخش فیلم های برتر، برنامه را دوباره اجرا کنید:
7. نمایش جزئیات فیلم و بازیگر
کاربر اکنون می تواند فیلم ها را مرور کند. هنگام ضربه زدن روی یک کارت فیلم، جزئیاتی در مورد فیلم به آنها نشان داده می شود، اما ممکن است متوجه شده باشید که جزئیات فاقد مقدار مشخصی از جزئیات هستند، خب...!
این به این دلیل است که ما فقط به همان اندازه که برای رندر کردن بخش قهرمان فیلم و بخش فیلم های برتر نیاز داشتیم، جزئیات مربوط به هر فیلم را دریافت کردیم: عنوان فیلم، توضیحات کوتاه و URL تصویر.
در صفحه جزئیات فیلم، می خواهیم اطلاعات بیشتری درباره فیلم نشان دهیم. در این بخش، برنامه را ارتقا می دهید تا بتواند بازیگران فیلم و هر نقدی را در صفحه جزئیات نمایش دهد.
برای این کار باید چند کار را انجام دهید:
- طرح واره را برای حمایت از بازیگران فیلم و نقدها تقویت کنید
- برای واکشی جزئیات درباره یک فیلم خاص، عبارت Firebase Data Connect را بنویسید
- نمایش نتایج در صفحه جزئیات فیلم
طرحواره را تقویت کنید
در VS Code، dataconnect/schema/schema.gql
باز کنید و تعاریف طرحواره Actor
و MovieActor
اضافه کنید.
## 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"
}
داده های ساختگی را برای بازیگران اضافه کنید
با به روز رسانی طرحواره، اکنون می توانید پایگاه داده را با داده های ساختگی بیشتری برای آزمایش پر کنید.
- در Finder،
finish/FriendlyFlix/dataconnect/moviededetails_insert.gql
در پوشهstart/FriendlyFlix/dataconnect
کپی کنید. - در VS Code،
dataconnect/moviededetails_insert.gql
باز کنید. - اطمینان حاصل کنید که شبیه سازها در افزونه Firebase Data Connect در حال اجرا هستند.
- شما باید یک دکمه Run (محلی) را در بالای فایل ببینید. روی این کلیک کنید تا داده های فیلم ساختگی را در پایگاه داده خود وارد کنید.
- پایانه اجرای Data Connect Execution را بررسی کنید تا تأیید کنید که داده ها با موفقیت اضافه شده اند.
با دادههای موجود، به مرحله بعدی بروید تا پرس و جو را برای واکشی جزئیات فیلم تعریف کنید.
کوئری GetMovieById را تعریف کنید
در VS Code، فایل dataconnect/connector/queries.gql
را باز کنید و کوئری GetMovieById
اضافه کنید:
## 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 را به MovieDetailsView وصل کنید
در Xcode، فایل MovieDetailsView.swift
را باز کنید و ویژگی محاسبه شده movieDetails
برای مطابقت با کد زیر به روز کنید:
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
}
}
برنامه را اجرا کنید
در Xcode، روی دکمه Run کلیک کنید تا برنامه در شبیه ساز iOS اجرا شود.
پس از راه اندازی برنامه، روی کارت فیلم ضربه بزنید تا جزئیات فیلم نمایش داده شود. باید به این شکل باشد:
8. احراز هویت کاربر را پیاده سازی کنید
در حال حاضر، این برنامه اطلاعات غیر شخصی فیلم و بازیگر را ارائه می دهد. در مراحل زیر، ویژگیهایی را پیادهسازی میکنید که دادهها را با کاربر واردشده مرتبط میکند. کار را با اجازه دادن به کاربران برای اضافه کردن فیلم به لیست تماشای شخصی خود شروع خواهید کرد.
قبل از اینکه بتوانید ویژگی فهرست تماشا را پیاده سازی کنید، ابتدا باید هویت کاربر را تعیین کنید. برای فعال کردن این کار، احراز هویت Firebase را ادغام میکنید و به کاربران اجازه میدهد وارد برنامه شوند.
شاید قبلاً دکمه آواتار کاربر را در سمت راست بالای صفحه اصلی مشاهده کرده باشید. با زدن این گزینه شما را به صفحه ای هدایت می کند که در آن کاربران می توانند با استفاده از ایمیل و رمز عبور خود ثبت نام کرده یا وارد سیستم شوند.
هنگامی که یک کاربر با موفقیت وارد سیستم شد، برنامه شما باید جزئیات ضروری خود را ذخیره کند، در درجه اول شناسه کاربری منحصر به فرد و نام کاربری انتخابی.
احراز هویت Firebase را فعال کنید
در کنسول Firebase برای پروژه خود، به بخش Authentication بروید و Firebase Authentication را فعال کنید. سپس، ارائه دهنده احراز هویت ایمیل/رمز عبور را فعال کنید.
در پوشه پروژه محلی خود، firebase.json
پیدا کنید و آن را به صورت زیر به روز کنید تا شبیه ساز Firebase Authentication فعال شود.
{
"emulators": {
"dataconnect": {
},
"auth": {
}
},
"dataconnect": {
"source": "dataconnect"
}
}
پس از این، باید شبیه ساز Firebase را متوقف کرده و مجدداً راه اندازی کنید تا تغییر اعمال شود.
یک کنترل کننده احراز هویت را پیاده سازی کنید
در بخش بعدی، منطقی را پیاده سازی می کنید که احراز هویت کاربر را با پایگاه داده شما متصل می کند. این شامل ایجاد یک کنترل کننده احراز هویت است که به ورودهای موفق گوش می دهد.
هنگامی که یک کاربر احراز هویت شد، این کنترل کننده به طور خودکار ایجاد حساب مربوطه خود را در پایگاه داده شما آغاز می کند.
در Xcode، فایل AuthenticationService.swift
را باز کنید و کد زیر را اضافه کنید:
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
}
}
این یک کنترلکننده احراز هویت عمومی است که به شما امکان میدهد onSignUp
برای ثبت بستهای استفاده کنید که پس از ورود کاربر فراخوانی میشود.
در داخل آن بسته شدن، می توانید یک حساب کاربری جدید در پایگاه داده ایجاد کنید. اما قبل از اینکه بتوانید این کار را انجام دهید، باید یک جهش ایجاد کنید که به شما امکان می دهد کاربران جدیدی را در پایگاه داده ایجاد یا به روز کنید.
یک موجودیت کاربر به طرحواره اضافه کنید
نوع User
یک موجودیت کاربر را تعریف می کند. کاربران می توانند با گذاشتن نظرات یا فیلم های مورد علاقه با فیلم ها تعامل داشته باشند.
در VS Code، فایل dataconnect/schema/schema.gql
را باز کنید و تعریف جدول User
زیر را اضافه کنید:
## 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)")
}
یک جهش برای درج یا به روز رسانی یک کاربر تعریف کنید
در VS Code، فایل dataconnect/connector/mutations.gql
را باز کنید و جهش UpsertUser
را اضافه کنید:
mutation UpsertUser($username: String!) @auth(level: USER) {
user_upsert(
data: {
id_expr: "auth.uid"
username: $username
}
)
}
پس از ورود با موفقیت یک کاربر جدید ایجاد کنید
در Xcode، FriendlyFlixApp.swift
را باز کنید و کد زیر را به مقداردهی اولیه اضافه کنید:
@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 {
...
}
}
این کد از upsertUserMutation
Firebase Data Connect که برای شما ایجاد شده است استفاده می کند تا هر زمان که کاربر با موفقیت با استفاده از Firebase Authentication ثبت نام کرد، یک کاربر جدید را وارد کنید (یا یک کاربر موجود را با همان شناسه به روز کنید).
آن را در عمل ببینید
برای تأیید اینکه این کار می کند، ابتدا در برنامه iOS ثبت نام کنید:
- اگر این کار را نکرده اید، شبیه ساز Firebase را متوقف کرده و مجددا راه اندازی کنید تا مطمئن شوید که شبیه ساز احراز هویت Firebase در حال اجرا است.
- در Xcode، روی دکمه Run کلیک کنید تا برنامه در شبیه ساز iOS اجرا شود.
- روی نماد آواتار در گوشه سمت راست بالای صفحه کلیک کنید.
- به جریان ثبت نام بروید و در برنامه ثبت نام کنید.
سپس، از پایگاه داده پرس و جو کنید تا تأیید کنید که برنامه یک حساب کاربری جدید برای کاربر ایجاد کرده است:
- در VS Code،
dataconnect/schema/schema.gql
باز کنید و روی Read data در موجودیتUser
کلیک کنید. - این یک فایل پرس و جو جدید به نام
User_read.gql
ایجاد می کند - روی Run local کلیک کنید تا همه کاربران در جدول کاربران را ببینید
- در پنجره Data Connect Execution، اکنون باید یک حساب کاربری را ببینید که به تازگی با آن ثبت نام کرده اید.
9. فیلم های مورد علاقه را مدیریت کنید
در این بخش از نرم افزار کد، تعاملات کاربر را در برنامه بررسی فیلم پیاده سازی خواهید کرد، به طور خاص به کاربران اجازه می دهید فیلم های مورد علاقه خود را مدیریت کنند. فیلمهایی که بهعنوان موارد دلخواه علامتگذاری شدهاند در بخش فهرست تماشای برنامه نمایش داده میشوند.
برای پشتیبانی از موارد دلخواه، طرح را تقویت کنید
نوع FavoriteMovie
یک جدول پیوستن است که روابط چند به چند بین کاربران و فیلم های مورد علاقه آنها را مدیریت می کند. هر جدول یک User
به یک Movie
پیوند می دهد.
قطعه کد را کپی کرده و در فایل dataconnect/schema/schema.gql
خود جایگذاری کنید:
type FavoriteMovie
@table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
## @ref is implicit
user: User!
movie: Movie!
}
جهش را برای افزودن و حذف موارد دلخواه تعریف کنید
قبل از اینکه برنامه بتواند فیلم های مورد علاقه کاربر را نمایش دهد، کاربر باید نشان دهد که کدام فیلم های مورد علاقه او هستند . برای رسیدن به این هدف، ابتدا باید دو جهش اضافه کنید تا یک فیلم را بهعنوان یکی از موارد دلخواه کاربر علامتگذاری کنید، یا به ترتیب آن را از فهرست علاقهمندان حذف کنید.
- در VS Code،
mutations.gql
درdataconnect/connector/mutations.gql
باز کنید - جهش های زیر را برای مدیریت فیلم های مورد علاقه اضافه کنید :
## 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 })
}
جهش ها را به رابط کاربری برنامه خود وصل کنید
کاربران می توانند با کلیک بر روی نماد قلب در صفحه جزئیات فیلم، یک فیلم را به عنوان فیلم مورد علاقه علامت گذاری کنند.
برای اتصال جهش هایی که ایجاد کرده اید به رابط کاربری برنامه، تغییرات زیر را در MovieCardView
انجام دهید:
-
FriendlyFlixSDK
را وارد کنید و کانکتور را راه اندازی کنید
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
...
}
- متد
toggleFavourite
را اجرا کنید. هر زمان که کاربر روی نماد قلب درMovieCardView
ضربه بزند، تماس گرفته می شود:
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)
}
}
}
}
این حالت مورد علاقه فیلم فعلی را در پایگاه داده به روز می کند. یکی از گام های نهایی که گم شده است این است که مطمئن شوید وضعیت رابط کاربری مطابق با آن منعکس می شود.
یک پرس و جو برای فهمیدن اینکه آیا یک فیلم به عنوان فیلم مورد علاقه علامت گذاری شده است تعریف کنید
- در VS Code،
queries.gql
درdataconnect/connector
باز کنید. - برای بررسی اینکه آیا یک فیلم به عنوان مورد علاقه علامت گذاری شده است، عبارت زیر را اضافه کنید:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
movieId
}
}
- در Xcode، یک ارجاع به جستار
GetIfFavoritedMovie
را وارد کنید و ویژگی محاسبه شده را پیاده سازی کنید که تعیین می کند آیا فیلم نمایش داده شده در اینMovieCardView
به عنوان فیلم دلخواه برای کاربر فعلی علامت گذاری شده است یا خیر.
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
}
...
}
- کد را در
toggleFavourite
به روز کنید تا هر زمان که کاربر روی دکمه ضربه زد، پرس و جو را اجرا کنید. این اطمینان حاصل می کند که ویژگی محاسبه شدهisFavourite
همیشه مقدار صحیح را برمی گرداند.
private func toggleFavourite() {
Task {
if isFavourite {
...
}
let _ = try await isFavouriteRef.execute()
}
}
فیلم های مورد علاقه را واکشی کنید
به عنوان آخرین مرحله برای این ویژگی، شما فیلمهای مورد علاقه کاربر را واکشی میکنید تا بتوانند آنها را در لیست تماشای خود ببینند.
- در VS Code،
queries.gql
درdataconnect/connector/queries.gql
باز کنید و عبارت زیر را جایگذاری کنید:
## 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
}
}
}
}
لیست فیلم های مورد علاقه کاربر در LibraryScreen
نمایش داده می شود. این صفحه فقط در صورتی باید داده ها را نمایش دهد که کاربر وارد سیستم شده باشد، بنابراین ابتدا وضعیت احراز هویت صفحه را به AuthenticationService
برنامه متصل می کنید.
- افزودن کد به نقشه از
FavoriteMovieFavoriteMovies
بهMovie
بهMovie+DataConnect.swift
:
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
}
}
- در Xcode،
LibraryScreen
را باز کنید، سپسisSignedIn
به صورت زیر به روز کنید:
struct LibraryScreen: View {
...
private var isSignedIn: Bool {
authenticationService.user != nil
}
}
- سپس Firebase Data Connect و FriendlyFlixSDK را وارد کنید و یک مرجع به جستار
GetUserFavoriteMovies
دریافت کنید:
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) ?? []
}
...
}
- اطمینان حاصل کنید که پرس و جو
watchListRef
زمانی که نمای ظاهر می شود اجرا می شود:
extension LibraryScreen: View {
var body: some View {
...
MovieListSection(namespace: namespace, title: "Watch List", movies: watchList)
.onAppear {
Task {
try await watchListRef.execute()
}
...
آن را در عمل ببینید
اکنون میتوانید برنامه را اجرا کنید و ویژگی مورد علاقهای را که به تازگی اجرا کردهاید، امتحان کنید. چند نکته را باید در نظر داشت:
- مطمئن شوید که شبیه ساز Firebase در حال اجرا است
- مطمئن شوید که داده های ساختگی را برای فیلم ها و جزئیات فیلم اضافه کرده اید
- مطمئن شوید که به عنوان کاربر ثبت نام کرده اید
- در Xcode، روی دکمه Run کلیک کنید تا برنامه در شبیه ساز iOS اجرا شود.
- پس از راه اندازی برنامه، روی کارت فیلم ضربه بزنید تا جزئیات فیلم نمایش داده شود.
- روی نماد قلب ضربه بزنید تا فیلم به عنوان مورد علاقه علامت گذاری شود. قلب باید جامد شود.
- این را برای چند فیلم تکرار کنید.
- به تب Library بروید. اکنون باید لیستی از تمام فیلم هایی که به عنوان موارد دلخواه علامت گذاری کرده اید را مشاهده کنید.
10. تبریک می گویم
تبریک میگوییم، شما با موفقیت Firebase Data Connect را به یک برنامه iOS اضافه کردید! اکنون مراحل کلیدی مورد نیاز برای راه اندازی Data Connect، ایجاد کوئری ها و جهش ها، و رسیدگی به احراز هویت کاربر را می دانید.
اختیاری: استقرار در تولید
این برنامه تاکنون فقط از شبیه سازهای Firebase استفاده کرده است. اگر می خواهید یاد بگیرید که چگونه این برنامه را در یک پروژه Firebase واقعی استقرار دهید، به مرحله بعدی ادامه دهید.
11. (اختیاری) برنامه خود را مستقر کنید
تاکنون این برنامه کاملاً محلی بوده است، همه دادهها در مجموعه Firebase Emulator موجود است. در این بخش یاد خواهید گرفت که چگونه پروژه Firebase خود را پیکربندی کنید تا این برنامه در مرحله تولید کار کند.
احراز هویت Firebase را فعال کنید
- در کنسول Firebase، به بخش Authentication بروید و روی شروع کلیک کنید.
- به برگه روش ورود به سیستم بروید.
- از قسمت ارائه دهندگان بومی گزینه ایمیل/رمز عبور را انتخاب کنید،
- ارائه دهنده ایمیل/گذرواژه را فعال کنید، سپس روی ذخیره کلیک کنید.
Firebase Data Connect را فعال کنید
مهم: اگر این اولین بار است که یک طرحواره را در پروژه خود اجرا می کنید، این فرآیند یک نمونه Cloud SQL PostgreSQL ایجاد می کند که می تواند حدود 15 دقیقه طول بکشد. تا زمانی که نمونه Cloud SQL آماده و با Firebase Data Connect یکپارچه نشود، نمیتوانید آن را مستقر کنید.
1. در رابط کاربری افزونه Firebase Data Connect VS Code، روی Deploy to production کلیک کنید. 2. ممکن است لازم باشد تغییرات طرحواره را بررسی کرده و تغییرات مخرب احتمالی را تأیید کنید. از شما خواسته می شود: - بررسی تغییرات طرحواره با استفاده از firebase dataconnect:sql:diff
- وقتی از تغییرات راضی بودید، آنها را با استفاده از جریان شروع شده توسط firebase dataconnect:sql:migrate
اعمال کنید.
Cloud SQL شما برای نمونه PostgreSQL با طرح و داده های مستقر نهایی به روز می شود. می توانید وضعیت را در کنسول Firebase نظارت کنید.
اکنون می توانید روی Run (Production) در پنل Firebase Data Connect کلیک کنید، همانطور که با شبیه سازهای محلی انجام دادید، تا داده ها را به محیط تولید اضافه کنید.
قبل از اجرای مجدد برنامه iOS، مطمئن شوید که به نمونه تولید پروژه شما متصل است:
- منوی Product > Scheme > Edit Scheme... را باز کنید.
- در بخش Run تیک آرگومان راه اندازی
-useEmulator YES
را بردارید.