১. শুরু করার আগে
এই কোডল্যাবটি আপনাকে এমন একটি iOS অ্যাপ্লিকেশন তৈরি করতে সাহায্য করবে, যা ‘সাইন ইন উইথ গুগল’ সুবিধাটি বাস্তবায়ন করে এবং সিমুলেটরে চলে। SwiftUI এবং UIKit উভয় ব্যবহার করে এর বাস্তবায়ন দেখানো হয়েছে।
SwiftUI হলো নতুন অ্যাপ তৈরির জন্য অ্যাপলের একটি আধুনিক UI ফ্রেমওয়ার্ক। এটি একটিমাত্র শেয়ার্ড কোডবেস থেকে অ্যাপলের সকল প্ল্যাটফর্মের জন্য ইউজার ইন্টারফেস তৈরি করতে সক্ষম করে। এর জন্য ন্যূনতম iOS 13 সংস্করণ প্রয়োজন।
UIKit হলো iOS-এর জন্য অ্যাপলের মূল এবং ভিত্তিগত UI ফ্রেমওয়ার্ক। এটি iOS-এর পুরোনো সংস্করণগুলোর জন্য ব্যাকওয়ার্ড কম্প্যাটিবিলিটি প্রদান করে। এই কারণে, প্রতিষ্ঠিত অ্যাপগুলোর জন্য এটি একটি ভালো পছন্দ, যেগুলোকে বিভিন্ন পুরোনো ডিভাইস সাপোর্ট করার প্রয়োজন হয়।
আপনি এমন একটি ফ্রেমওয়ার্কের পথ অনুসরণ করতে পারেন যা আপনার উন্নয়নের চাহিদার সাথে সবচেয়ে ভালোভাবে সামঞ্জস্যপূর্ণ।
পূর্বশর্ত
আপনি যা শিখবেন
- কীভাবে একটি গুগল ক্লাউড প্রজেক্ট তৈরি করবেন
- গুগল ক্লাউড কনসোলে কীভাবে OAuth ক্লায়েন্ট তৈরি করবেন
- আপনার iOS অ্যাপে কীভাবে গুগল দিয়ে সাইন ইন চালু করবেন
- কীভাবে গুগল দিয়ে সাইন ইন বাটনটি কাস্টমাইজ করবেন
- একটি আইডি টোকেন কীভাবে ডিকোড করবেন
- আপনার iOS অ্যাপের জন্য অ্যাপ চেক কীভাবে চালু করবেন
আপনার যা যা লাগবে
- Xcode- এর একটি বর্তমান সংস্করণ
- ম্যাকওএস চালিত এমন একটি কম্পিউটার যা আপনার ইনস্টল করা এক্সকোড সংস্করণের জন্য সিস্টেমের প্রয়োজনীয়তা পূরণ করে।
এই কোডল্যাবটি Xcode 16.3 এবং iOS 18.3 সিমুলেটর ব্যবহার করে তৈরি করা হয়েছে। ডেভেলপমেন্টের জন্য আপনার Xcode-এর সর্বশেষ সংস্করণ ব্যবহার করা উচিত।
২. একটি নতুন Xcode প্রজেক্ট তৈরি করুন
- Xcode খুলুন এবং 'Create a new Xcode project' নির্বাচন করুন।
- iOS ট্যাবটি বেছে নিন, অ্যাপ টেমপ্লেটটি নির্বাচন করুন এবং Next-এ ক্লিক করুন।

- প্রকল্পের বিকল্পগুলিতে:
- আপনার পণ্যের নাম লিখুন।
- ঐচ্ছিকভাবে আপনার দল নির্বাচন করুন।
- আপনার প্রতিষ্ঠানের শনাক্তকারী নম্বরটি প্রবেশ করান।
- তৈরি হওয়া বান্ডেল আইডেন্টিফায়ারটি লিখে রাখুন। পরবর্তীতে আপনার এটি প্রয়োজন হবে।
- ইন্টারফেসের জন্য, নিম্নলিখিতগুলির মধ্যে যেকোনো একটি বেছে নিন:
- SwiftUI-ভিত্তিক অ্যাপের জন্য SwiftUI ।
- UIKit-ভিত্তিক অ্যাপের জন্য স্টোরিবোর্ড ।
- ভাষা হিসেবে সুইফট বেছে নিন।
- পরবর্তী ধাপে যান এবং আপনার প্রজেক্টটি সংরক্ষণ করার জন্য একটি স্থান বেছে নিন।

৩. একটি OAuth ক্লায়েন্ট তৈরি করুন
আপনার অ্যাপকে গুগলের অথেনটিকেশন সার্ভিসের সাথে যোগাযোগ করার অনুমতি দিতে, আপনাকে একটি OAuth ক্লায়েন্ট আইডি তৈরি করতে হবে। এর জন্য একটি গুগল ক্লাউড প্রজেক্ট প্রয়োজন। নিম্নলিখিত ধাপগুলো আপনাকে একটি প্রজেক্ট এবং একটি OAuth ক্লায়েন্ট আইডি তৈরির প্রক্রিয়াটি ধাপে ধাপে দেখিয়ে দেবে।
একটি গুগল ক্লাউড প্রজেক্ট নির্বাচন করুন বা তৈরি করুন
- গুগল ক্লাউড কনসোলে যান এবং একটি প্রজেক্ট নির্বাচন করুন বা তৈরি করুন। আপনি যদি আগে থেকে বিদ্যমান কোনো প্রজেক্ট নির্বাচন করেন, তাহলে কনসোলটি স্বয়ংক্রিয়ভাবে আপনাকে পরবর্তী প্রয়োজনীয় ধাপে নিয়ে যাবে।

- আপনার নতুন গুগল ক্লাউড প্রজেক্টের জন্য একটি নাম দিন।
- তৈরি করুন নির্বাচন করুন।

আপনার সম্মতি স্ক্রিন কনফিগার করুন
আপনি যদি নির্বাচিত প্রজেক্টের জন্য ইতিমধ্যেই একটি কনসেন্ট স্ক্রিন কনফিগার করে থাকেন, তাহলে আপনাকে এখন এটি কনফিগার করার জন্য অনুরোধ করা হবে না। সেক্ষেত্রে, আপনি এই অংশটি এড়িয়ে যেতে পারেন এবং 'Create an OAuth 2.0 client' অংশে চলে যেতে পারেন।
- সম্মতি স্ক্রিন কনফিগার করুন নির্বাচন করুন।

- ব্র্যান্ডিং পেজে ' Get started' নির্বাচন করুন।

- প্রজেক্ট কনফিগারেশন পেজে নিম্নলিখিত ফিল্ডগুলি পূরণ করুন:
- অ্যাপের তথ্য : আপনার অ্যাপের জন্য একটি নাম এবং একটি ব্যবহারকারী সহায়তা ইমেল দিন। এই সহায়তা ইমেলটি সর্বজনীনভাবে প্রদর্শিত হবে, যাতে ব্যবহারকারীরা তাদের সম্মতি সংক্রান্ত প্রশ্ন নিয়ে আপনার সাথে যোগাযোগ করতে পারেন।
- দর্শক : বাহ্যিক নির্বাচন করুন।
- যোগাযোগের তথ্য : আপনার প্রকল্প সম্পর্কে গুগল যাতে আপনার সাথে যোগাযোগ করতে পারে, তার জন্য একটি ইমেল ঠিকানা লিখুন।
- গুগল এপিআই পরিষেবা: ব্যবহারকারীর ডেটা নীতি পর্যালোচনা করুন।
- তৈরি করুন- এ ক্লিক করুন।

- ন্যাভিগেশন মেনু থেকে ক্লায়েন্ট পৃষ্ঠাটি নির্বাচন করুন।
- ক্লায়েন্ট তৈরি করুন -এ ক্লিক করুন।

একটি OAuth 2.0 ক্লায়েন্ট তৈরি করুন
- অ্যাপ্লিকেশনের ধরন হিসেবে iOS নির্বাচন করুন।
- আপনার ক্লায়েন্টের জন্য একটি নাম লিখুন।
- শেষ ধাপে তৈরি করা বান্ডেল আইডেন্টিফায়ারটি প্রবেশ করান।
- Apple কর্তৃক আপনার টিমকে বরাদ্দ করা টিম আইডিটি প্রবেশ করান। এই ধাপটি আপাতত ঐচ্ছিক, কিন্তু এই কোডল্যাবের পরবর্তী অংশে অ্যাপ চেক (App Check) চালু করার জন্য একটি টিম আইডি প্রয়োজন হবে।
- তৈরি করুন নির্বাচন করুন।

- ডায়ালগ উইন্ডো থেকে ক্লায়েন্ট আইডিটি কপি করুন, পরবর্তীতে আপনার এটি প্রয়োজন হবে।
- পরবর্তীতে ব্যবহারের জন্য plist ফাইলটি ডাউনলোড করুন।

৪. আপনার Xcode প্রজেক্ট কনফিগার করুন
পরবর্তী ধাপ হলো ‘সাইন ইন উইথ গুগল এসডিকে’-এর সাথে কাজ করার জন্য আপনার এক্সকোড প্রজেক্ট সেট আপ করা। এই প্রক্রিয়ার জন্য এসডিকে-টিকে আপনার প্রজেক্টে একটি ডিপেন্ডেন্সি হিসেবে যুক্ত করতে হবে এবং একটি অনন্য ক্লায়েন্ট আইডি দিয়ে আপনার প্রজেক্ট সেটিংস কনফিগার করতে হবে। এই আইডিটি সাইন-ইন প্রক্রিয়ার সময় এসডিকে-কে গুগলের অথেনটিকেশন সার্ভিসের সাথে নিরাপদে যোগাযোগ করতে সাহায্য করে।
গুগল দিয়ে সাইন ইন করার নির্ভরতাগুলি ইনস্টল করুন
- আপনার Xcode প্রজেক্টটি খুলুন।
- ফাইল > প্যাকেজ নির্ভরতা যোগ করুন -এ যান।
- সার্চ বারে, 'Sign in with Google' রিপোজিটরির URL-টি লিখুন: https://github.com/google/GoogleSignIn-iOS

- প্যাকেজ যোগ করুন নির্বাচন করুন।
- GoogleSignIn প্যাকেজের জন্য মূল অ্যাপ্লিকেশন টার্গেট নির্বাচন করুন।
- আপনি যদি SwiftUI ব্যবহার করেন, তাহলে GoogleSignInSwift প্যাকেজের জন্য মূল অ্যাপ্লিকেশন টার্গেটটি নির্বাচন করুন। আপনি যদি UIKit ব্যবহার করার পরিকল্পনা করেন, তাহলে এই প্যাকেজের জন্য কোনো টার্গেট নির্বাচন করবেন না।
- প্যাকেজ যোগ করুন নির্বাচন করুন।

আপনার অ্যাপের ক্রেডেনশিয়াল কনফিগার করুন।
- প্রজেক্ট নেভিগেটরে, আপনার প্রজেক্টের রুটে ক্লিক করুন।
- মূল এডিটর অংশে, টার্গেটস (TARGETS) তালিকা থেকে আপনার মূল অ্যাপ্লিকেশন টার্গেটটি নির্বাচন করুন।
- এডিটর এলাকার শীর্ষে থাকা তথ্য ট্যাবটি নির্বাচন করুন।
- কাস্টম আইওএস টার্গেট প্রোপার্টিজ সেকশনের শেষ সারির উপর মাউস রাখুন এবং প্রদর্শিত + বোতামটিতে ক্লিক করুন।

- Key কলামে GIDClientID টাইপ করুন।
- 'Value' কলামে, গুগল ক্লাউড কনসোল থেকে কপি করা ক্লায়েন্ট আইডিটি পেস্ট করুন।

- গুগল ক্লাউড কনসোল থেকে ডাউনলোড করা plist ফাইলটি খুলুন।
- রিভার্সড ক্লায়েন্ট আইডি- এর মানটি কপি করুন।

- Info ট্যাবের একেবারে নিচে থাকা URL Types অংশটি প্রসারিত করুন।
- + বোতামটি নির্বাচন করুন।
- URL Schemes বক্সে রিভার্সড ক্লায়েন্ট আইডিটি প্রবেশ করান।

এখন আমরা আমাদের অ্যাপে সাইন-ইন বাটন যোগ করার জন্য প্রস্তুত!
৫. সাইন-ইন বাটন যোগ করুন
Xcode প্রজেক্টটি কনফিগার করা হয়ে গেলে, এবার অ্যাপটিতে ‘Sign in with Google’ বাটনটি যোগ করার পালা!
এই ধাপের মূল লজিকটি হলো GIDSignIn.sharedInstance.signIn কে কল করা। এই মেথডটি অথেনটিকেশন প্রক্রিয়া শুরু করে এবং ব্যবহারকারীর কাছে 'সাইন ইন উইথ গুগল' ফ্লোটি উপস্থাপন করার জন্য 'সাইন ইন উইথ গুগল' SDK-এর কাছে নিয়ন্ত্রণ হস্তান্তর করে।
SwiftUI
- এক্সকোড প্রজেক্ট নেভিগেটরে ContentView.swift ফাইলটি খুঁজুন।
- এই ফাইলের বিষয়বস্তু নিম্নলিখিত লেখা দিয়ে প্রতিস্থাপন করুন:
import GoogleSignIn
import GoogleSignInSwift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
GoogleSignInButton(action: handleSignInButton).padding()
}
}
func handleSignInButton() {
// Find the current window scene.
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
print("There is no active window scene")
return
}
// Get the root view controller from the window scene.
guard
let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
.rootViewController
else {
print("There is no key window or root view controller")
return
}
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(
withPresenting: rootViewController
) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
// If sign in succeeded, display the app's main content View.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
}
}
}
#Preview {
ContentView()
}

UIKit
- এক্সকোড প্রজেক্ট নেভিগেটরে ViewController.swift ফাইলটি খুঁজুন।
- এই ফাইলের বিষয়বস্তু নিম্নলিখিত লেখা দিয়ে প্রতিস্থাপন করুন:
import GoogleSignIn
import UIKit
class ViewController: UIViewController {
// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()
override func viewDidLoad() {
super.viewDidLoad()
// Add the sign-in button to your view
view.addSubview(signInButton)
// Position the button using constraints
signInButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
// Add a target to the button to call a method when it's pressed
signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
}
// This method is called when the sign-in button is pressed.
@objc func signInButtonTapped() {
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
// If sign in succeeded, print the ID token.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
}
}
}

সাইন-ইন বোতামটি দেখুন
সিমুলেটরে আপনার অ্যাপটি চালু করুন। আপনি ‘Sign in with Google’ বাটনটি দেখতে পাবেন, কিন্তু এটি এখনই ঠিকমতো কাজ করবে না। এটি স্বাভাবিক, কারণ ব্যবহারকারী প্রমাণীকরণের পর তাকে আপনার অ্যাপে ফিরিয়ে আনার জন্য প্রয়োজনীয় কোডটি আপনাকে এখনও যুক্ত করতে হবে।
৬. সাইন-ইন বাটনটি কাস্টমাইজ করুন
আপনার অ্যাপের থিমের সাথে আরও ভালোভাবে মানিয়ে নেওয়ার জন্য আপনি ডিফল্ট 'সাইন-ইন উইথ গুগল' বাটনটি কাস্টমাইজ করতে পারেন। 'সাইন-ইন উইথ গুগল' এসডিকে আপনাকে বাটনটির কালার স্কিম এবং স্টাইল পরিবর্তন করার সুযোগ দেয়।
SwiftUI
এই কোড লাইনটির মাধ্যমে পেজে ডিফল্ট বাটনটি যোগ করা হয়:
GoogleSignInButton(action: handleSignInButton)
GoogleSignInButton এর ইনিশিয়ালাইজারে প্যারামিটার পাস করে কাস্টমাইজ করা হয়। নিচের কোডটি সাইন-ইন বাটনটিকে ডার্ক মোডে প্রদর্শন করবে।
- ContentView.swift খুলুন
-
GoogleSignInButtonএর ইনিশিয়ালাইজারটি আপডেট করে নিম্নলিখিত মানগুলি অন্তর্ভুক্ত করুন:
GoogleSignInButton(
scheme: .dark, // Options: .light, .dark, .auto
style: .standard, // Options: .standard, .wide, .icon
state: .normal, // Options: .normal, .disabled
action: handleSignInButton
).padding()

কাস্টমাইজেশন বিকল্পগুলি সম্পর্কে আরও তথ্যের জন্য GoogleSignInSwift ফ্রেমওয়ার্ক রেফারেন্স দেখুন।
UIKit
ডিফল্ট বাটনটি এই কোড লাইনগুলো দিয়ে তৈরি করা হয়:
// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()
// Add the button to your view
view.addSubview(signInButton)
বাটন ইনস্ট্যান্সে প্রোপার্টি সেট করার মাধ্যমে GIDSignInButton কে কাস্টমাইজ করা হয়। নিচের কোডটি সাইন-ইন বাটনটিকে ডার্ক মোডে প্রদর্শন করবে।
- ViewController.swift খুলুন।
-
viewDidLoadফাংশনে, ভিউতে সাইন-ইন বাটন যোগ করার ঠিক আগে নিম্নলিখিত কোড লাইনগুলো যোগ করুন:
// Set the width and color of the sign-in button
signInButton.style = .standard // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark // Options: .dark, .light

কাস্টমাইজেশন সম্পর্কে আরও তথ্যের জন্য GoogleSignIn ফ্রেমওয়ার্ক রেফারেন্স দেখুন।
৭. প্রমাণীকরণ পুনঃনির্দেশ URL পরিচালনা করুন
সাইন-ইন বাটনটি যুক্ত করার পর, পরবর্তী ধাপ হলো ব্যবহারকারীর প্রমাণীকরণের পরে যে রিডাইরেক্ট হয়, তা পরিচালনা করা। প্রমাণীকরণের পরে, গুগল একটি অস্থায়ী অনুমোদন কোডসহ একটি ইউআরএল ফেরত দেয়। সাইন-ইন প্রক্রিয়াটি সম্পূর্ণ করতে, একটি হ্যান্ডলার এই ইউআরএলটি গ্রহণ করে এবং একটি স্বাক্ষরিত আইডি টোকেন (JWT)-এর বিনিময়ের জন্য এটিকে 'সাইন ইন উইথ গুগল এসডিকে'-তে পাঠিয়ে দেয়।
SwiftUI
- আপনার
Appstruct ধারণকারী ফাইলটি খুলুন। এই ফাইলটির নামকরণ আপনার প্রোজেক্টের উপর ভিত্তি করে করা হয়, তাই নামটি YourProjectNameApp.swift-এর মতো হবে। - এই ফাইলের বিষয়বস্তু নিম্নলিখিত লেখা দিয়ে প্রতিস্থাপন করুন:
import GoogleSignIn
import SwiftUI
@main
struct iOS_Sign_in_with_Google_App: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
GIDSignIn.sharedInstance.handle(url)
}
}
}
}
UIKit
- AppDelegate.swift খুলুন।
- ফাইলের শীর্ষে নিম্নলিখিত ইম্পোর্টটি যোগ করুন:
import GoogleSignIn
-
AppDelegateক্লাসের ভিতরে নিম্নলিখিত অথেনটিকেশন হ্যান্ডলার ফাংশনটি যোগ করুন। এটি রাখার জন্য একটি ভালো জায়গা হলোapplication(_:didFinishLaunchingWithOptions:)মেথডের ক্লোজিং ব্রেসের ঠিক পরেই:
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
var handled: Bool
handled = GIDSignIn.sharedInstance.handle(url)
if handled {
return true
}
// If not handled by this app, return false.
return false
}
এই পরিবর্তনগুলো করার পর, আপনার AppDelegate.swift ফাইলটি দেখতে এইরকম হবে:
import GoogleSignIn
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Override point for customization after application launch.
return true
}
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
var handled: Bool
handled = GIDSignIn.sharedInstance.handle(url)
if handled {
return true
}
// If not handled by this app, return false.
return false
}
// MARK: UISceneSession Lifecycle
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
func application(
_ application: UIApplication,
didDiscardSceneSessions sceneSessions: Set<UISceneSession>
) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
সাইন-ইন প্রবাহ পরীক্ষা করুন
আপনি এখন সম্পূর্ণ সাইন-ইন প্রক্রিয়াটি পরীক্ষা করতে পারেন!
আপনার অ্যাপটি চালু করুন এবং সাইন-ইন বোতামে ট্যাপ করুন। আপনার প্রমাণীকরণের পর, গুগল একটি সম্মতি স্ক্রিন দেখাবে যেখানে আপনি অ্যাপটিকে আপনার তথ্য অ্যাক্সেস করার অনুমতি দিতে পারবেন। আপনি অনুমোদন করলেই সাইন-ইন প্রক্রিয়াটি চূড়ান্ত হবে এবং আপনাকে অ্যাপে ফিরিয়ে আনা হবে।
যখন সাইন-ইন প্রক্রিয়াটি সফলভাবে সম্পন্ন হয়, তখন ‘সাইন ইন উইথ গুগল এসডিকে’ ব্যবহারকারীর ক্রেডেনশিয়ালগুলো ডিভাইসের কীচেইনে নিরাপদে সংরক্ষণ করে। পরবর্তীতে অ্যাপটি চালু করার সময় ব্যবহারকারীকে সাইন-ইন করা অবস্থায় রাখার জন্য এই ক্রেডেনশিয়ালগুলো ব্যবহার করা যেতে পারে।
৮. একটি সাইন-আউট বাটন যোগ করুন
এখন যেহেতু সাইন-ইন কাজ করছে, পরবর্তী ধাপ হলো একটি সাইন-আউট বাটন যোগ করা এবং ব্যবহারকারীর বর্তমান সাইন-ইন অবস্থা অনুযায়ী UI আপডেট করা। সাইন-ইন সফল হলে, SDK একটি GIDGoogleUser অবজেক্ট প্রদান করে। এই অবজেক্টটিতে একটি profile প্রপার্টি থাকে, যেখানে ব্যবহারকারীর নাম এবং ইমেলের মতো মৌলিক তথ্য থাকে, যা আপনি UI ব্যক্তিগতকরণ করতে ব্যবহার করবেন।
SwiftUI
- আপনার ContentView.swift ফাইলটি খুলুন।
- আপনার
ContentViewstruct-এর শুরুতে একটি স্টেট ভ্যারিয়েবল যোগ করুন। ব্যবহারকারী সাইন ইন করার পর এই ভ্যারিয়েবলটি তার তথ্য ধারণ করবে। যেহেতু এটি একটি@Stateভ্যারিয়েবল, তাই এর মান পরিবর্তন হলেই SwiftUI স্বয়ংক্রিয়ভাবে আপনার UI আপডেট করে দেবে।
struct ContentView: View {
@State private var user: GIDGoogleUser?
}
- আপনার
ContentViewstruct-এর বর্তমানbodyনিম্নলিখিতVStackদিয়ে প্রতিস্থাপন করুন। এটি পরীক্ষা করবে যেuserস্টেট ভেরিয়েবলটিতে কোনো ব্যবহারকারী আছে কিনা। যদি থাকে, তবে এটি একটি স্বাগত বার্তা এবং একটি সাইন-আউট বাটন দেখাবে। আর যদি না থাকে, তবে এটি আসল 'Sign in with Google' বাটনটি দেখাবে:
var body: some View {
VStack {
// Check if the user is signed in.
if let user = user {
// If signed in, show a welcome message and the sign-out button.
Text("Hello, \(user.profile?.givenName ?? "User")!")
.font(.title)
.padding()
Button("Sign Out", action: signOut)
.buttonStyle(.borderedProminent)
} else {
// If not signed in, show the "Sign in with Google" button.
GoogleSignInButton(
scheme: .dark, // Options: .light, .dark, .auto
style: .standard, // Options: .standard, .wide, .icon
state: .normal, // Options: .normal, .disabled
action: handleSignInButton
).padding()
}
}
}
-
handleSignInButtonকমপ্লিশন ব্লকটি আপডেট করেsignInResult.userকে আপনার নতুনuserভেরিয়েবলে অ্যাসাইন করুন। এটিই UI-কে সাইন-ইন করা ভিউতে পরিবর্তন করতে ট্রিগার করে:
func handleSignInButton() {
// Find the current window scene.
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
print("There is no active window scene")
return
}
// Get the root view controller from the window scene.
guard
let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
.rootViewController
else {
print("There is no key window or root view controller")
return
}
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(
withPresenting: rootViewController
) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
DispatchQueue.main.async {
self.user = result.user
}
// If sign in succeeded, display the app's main content View.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
}
}
- আপনার সাইন-আউট বাটন দ্বারা কল করার জন্য, আপনার
ContentViewstruct-এর শেষে একটি নতুনsignOutফাংশন যোগ করুন:
func signOut() {
GIDSignIn.sharedInstance.signOut()
// After signing out, set the `user` state variable to `nil`.
self.user = nil
}
অ্যাপটি চালু করুন এবং সাইন ইন করুন। সফলভাবে প্রমাণীকরণের পর আপনি ইউজার ইন্টারফেসে (UI) পরিবর্তন দেখতে পাবেন!

এই পরিবর্তনগুলো করার পর, আপনার ContentView.swift ফাইলটি দেখতে এইরকম হবে:
import GoogleSignIn
import GoogleSignInSwift
import SwiftUI
struct ContentView: View {
@State private var user: GIDGoogleUser?
var body: some View {
VStack {
// Check if the user is signed in.
if let user = user {
// If signed in, show a welcome message and the sign-out button.
Text("Hello, \(user.profile?.givenName ?? "User")!")
.font(.title)
.padding()
Button("Sign Out", action: signOut)
.buttonStyle(.borderedProminent)
} else {
// If not signed in, show the "Sign in with Google" button.
GoogleSignInButton(
scheme: .dark, // Options: .light, .dark, .auto
style: .standard, // Options: .standard, .wide, .icon
state: .normal, // Options: .normal, .disabled
action: handleSignInButton
).padding()
}
}
}
func handleSignInButton() {
// Find the current window scene.
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
print("There is no active window scene")
return
}
// Get the root view controller from the window scene.
guard
let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
.rootViewController
else {
print("There is no key window or root view controller")
return
}
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(
withPresenting: rootViewController
) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
DispatchQueue.main.async {
self.user = result.user
}
// If sign in succeeded, display the app's main content View.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
}
}
func signOut() {
GIDSignIn.sharedInstance.signOut()
// After signing out, set the `user` state variable to `nil`.
self.user = nil
}
}
#Preview {
ContentView()
}
UIKit
- ViewController.swift খুলুন।
-
ViewControllerএর একদম উপরে, যেখানে আপনিsignInButtonডিক্লেয়ার করেছেন তার ঠিক নিচে, একটি সাইন-আউট বাটন এবং একটি ওয়েলকাম লেবেল যোগ করুন:
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
-
ViewControllerএর শেষে নিম্নলিখিত ফাংশনটি যোগ করুন। এই ফাংশনটি ব্যবহারকারীর সাইন-ইন স্ট্যাটাসের উপর ভিত্তি করে তাকে ভিন্ন ভিন্ন UI দেখাবে:
private func updateUI(for user: GIDGoogleUser?) {
if let user = user {
// User is signed in.
signInButton.isHidden = true
signOutButton.isHidden = false
welcomeLabel.isHidden = false
welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
} else {
// User is signed out.
signInButton.isHidden = false
signOutButton.isHidden = true
welcomeLabel.isHidden = true
}
}
- ভিউতে ওয়েলকাম লেবেল এবং সাইন-আউট বাটন যোগ করতে,
viewDidLoadফাংশনের শেষে নিম্নলিখিত কোডটি যোগ করুন:
// --- Set up the Welcome Label ---
welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
welcomeLabel.textAlignment = .center
welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
view.addSubview(welcomeLabel)
NSLayoutConstraint.activate([
welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
])
// --- Set up the Sign-Out Button ---
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
view.addSubview(signOutButton)
NSLayoutConstraint.activate([
signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
])
signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)
// --- Set Initial UI State ---
updateUI(for: nil)
- সফল সাইন-ইন হলে
UpdateUIমেথডটি কল করার জন্যsignInButtonTappedফাংশনটি আপডেট করুন:
@objc func signInButtonTapped() {
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
// If sign in succeeded, print the ID token.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
DispatchQueue.main.async {
self.updateUI(for: result.user)
}
}
}
- অবশেষে, সাইন-আউট প্রক্রিয়াটি পরিচালনা করার জন্য
ViewControllerএ একটিsignOutButtonTappedফাংশন যোগ করুন:
@objc func signOutButtonTapped() {
GIDSignIn.sharedInstance.signOut()
// Update the UI for the signed-out state.
updateUI(for: nil)
}
অ্যাপটি চালু করুন এবং সাইন ইন করুন। সফলভাবে প্রমাণীকরণের পর আপনি ইউজার ইন্টারফেসে (UI) পরিবর্তন দেখতে পাবেন!

এই পরিবর্তনগুলো করার পর, আপনার ViewController.swift ফাইলটি দেখতে এইরকম হবে:
import GoogleSignIn
import UIKit
class ViewController: UIViewController {
// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Set the width and color of the sign-in button
signInButton.style = .standard // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark // Options: .dark, .light
// Add the sign-in button to your view
view.addSubview(signInButton)
// Position the button using constraints
signInButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
// Add a target to the button to call a method when it's pressed
signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
// --- Set up the Welcome Label ---
welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
welcomeLabel.textAlignment = .center
welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
view.addSubview(welcomeLabel)
NSLayoutConstraint.activate([
welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
])
// --- Set up the Sign-Out Button ---
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
view.addSubview(signOutButton)
NSLayoutConstraint.activate([
signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
])
signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)
// --- Set Initial UI State ---
updateUI(for: nil)
}
// This method is called when the sign-in button is pressed.
@objc func signInButtonTapped() {
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
// If sign in succeeded, print the ID token.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
DispatchQueue.main.async {
self.updateUI(for: result.user)
}
}
}
private func updateUI(for user: GIDGoogleUser?) {
if let user = user {
// User is signed in.
signInButton.isHidden = true
signOutButton.isHidden = false
welcomeLabel.isHidden = false
welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
} else {
// User is signed out.
signInButton.isHidden = false
signOutButton.isHidden = true
welcomeLabel.isHidden = true
}
}
@objc func signOutButtonTapped() {
GIDSignIn.sharedInstance.signOut()
// Update the UI for the signed-out state.
updateUI(for: nil)
}
}
৯. ব্যবহারকারীর সাইন-ইন অবস্থা পুনরুদ্ধার করুন
পুরনো ব্যবহারকারীদের অভিজ্ঞতা উন্নত করার জন্য, পরবর্তী পদক্ষেপ হলো অ্যাপ চালু করার সময় তাদের সাইন-ইন অবস্থা পুনরুদ্ধার করা। restorePreviousSignIn কল করলে Keychain-এ সংরক্ষিত ক্রেডেনশিয়াল ব্যবহার করে ব্যবহারকারীকে নীরবে পুনরায় সাইন-ইন করানো হয়, যা নিশ্চিত করে যে তাদের প্রতিবার সাইন-ইন প্রক্রিয়াটি সম্পূর্ণ করতে হবে না।
SwiftUI
- ContentView.swift খুলুন।
- নিম্নলিখিত কোডটি
VStackএর ঠিক পরেইbodyভেরিয়েবলের ভিতরে যোগ করুন:
.onAppear {
// On appear, try to restore a previous sign-in.
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
// This closure is called when the restoration is complete.
if let user = user {
// If a user was restored, update the `user` state variable.
DispatchQueue.main.async {
self.user = user
}
// Print the ID token to the console when restored.
print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
}
}
}
আপনার ContentView.swift দেখতে এইরকম হওয়া উচিত:
import GoogleSignIn
import GoogleSignInSwift
import SwiftUI
struct ContentView: View {
@State private var user: GIDGoogleUser?
var body: some View {
VStack {
// Check if the user is signed in.
if let user = user {
// If signed in, show a welcome message and the sign-out button.
Text("Hello, \(user.profile?.givenName ?? "User")!")
.font(.title)
.padding()
Button("Sign Out", action: signOut)
.buttonStyle(.borderedProminent)
} else {
// If not signed in, show the "Sign in with Google" button.
GoogleSignInButton(
scheme: .dark, // Options: .light, .dark, .auto
style: .standard, // Options: .standard, .wide, .icon
state: .normal, // Options: .normal, .disabled
action: handleSignInButton
).padding()
}
}
.onAppear {
// On appear, try to restore a previous sign-in.
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
// This closure is called when the restoration is complete.
if let user = user {
// If a user was restored, update the `user` state variable.
DispatchQueue.main.async {
self.user = user
}
// Print the ID token to the console when restored.
print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
}
}
}
}
func handleSignInButton() {
// Find the current window scene.
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
print("There is no active window scene")
return
}
// Get the root view controller from the window scene.
guard
let rootViewController = windowScene.windows.first(where: { $0.isKeyWindow })?
.rootViewController
else {
print("There is no key window or root view controller")
return
}
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(
withPresenting: rootViewController
) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
DispatchQueue.main.async {
self.user = result.user
}
// If sign in succeeded, display the app's main content View.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
}
}
func signOut() {
GIDSignIn.sharedInstance.signOut()
// After signing out, set the `user` state variable to `nil`.
self.user = nil
}
}
#Preview {
ContentView()
}
UIKit
- ViewController.swift খুলুন।
-
viewDidLoadমেথডের শেষে নিম্নলিখিতrestorePreviousSignInকলটি যোগ করুন:
// Attempt to restore a previous sign-in session
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
if let user = user {
print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")
// Print the ID token when a session is restored.
print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
// On success, update the UI for the signed-in state on the main thread.
DispatchQueue.main.async {
self.updateUI(for: user)
}
}
}
আপনার ViewController.swift ফাইলটি দেখতে এইরকম হওয়া উচিত:
import GoogleSignIn
import UIKit
class ViewController: UIViewController {
// Create an instance of the Sign in with Google button
let signInButton = GIDSignInButton()
let signOutButton = UIButton(type: .system)
let welcomeLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Set the width and color of the sign-in button
signInButton.style = .standard // Options: .standard, .wide, .iconOnly
signInButton.colorScheme = .dark // Options: .dark, .light
// Add the sign-in button to your view
view.addSubview(signInButton)
// Position the button using constraints
signInButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
signInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signInButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
// Add a target to the button to call a method when it's pressed
signInButton.addTarget(self, action: #selector(signInButtonTapped), for: .touchUpInside)
// --- Set up the Welcome Label ---
welcomeLabel.translatesAutoresizingMaskIntoConstraints = false
welcomeLabel.textAlignment = .center
welcomeLabel.font = .systemFont(ofSize: 24, weight: .bold)
view.addSubview(welcomeLabel)
NSLayoutConstraint.activate([
welcomeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
welcomeLabel.bottomAnchor.constraint(equalTo: signInButton.topAnchor, constant: -20),
])
// --- Set up the Sign-Out Button ---
signOutButton.translatesAutoresizingMaskIntoConstraints = false
signOutButton.setTitle("Sign Out", for: .normal)
view.addSubview(signOutButton)
NSLayoutConstraint.activate([
signOutButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
signOutButton.topAnchor.constraint(equalTo: signInButton.bottomAnchor, constant: 20),
])
signOutButton.addTarget(self, action: #selector(signOutButtonTapped), for: .touchUpInside)
// --- Set Initial UI State ---
updateUI(for: nil)
// Attempt to restore a previous sign-in session
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
if let user = user {
print("Successfully restored sign-in for user: \(user.profile?.givenName ?? "Unknown")")
// Print the ID token when a session is restored.
print("Restored ID Token: \(user.idToken?.tokenString ?? "")")
// On success, update the UI for the signed-in state on the main thread.
DispatchQueue.main.async {
self.updateUI(for: user)
}
}
}
}
// This method is called when the sign-in button is pressed.
@objc func signInButtonTapped() {
// Start the sign-in process.
GIDSignIn.sharedInstance.signIn(withPresenting: self) { signInResult, error in
guard let result = signInResult else {
// Inspect error
print("Error signing in: \(error?.localizedDescription ?? "No error description")")
return
}
// If sign in succeeded, print the ID token.
print("ID Token: \(result.user.idToken?.tokenString ?? "")")
DispatchQueue.main.async {
self.updateUI(for: result.user)
}
}
}
private func updateUI(for user: GIDGoogleUser?) {
if let user = user {
// User is signed in.
signInButton.isHidden = true
signOutButton.isHidden = false
welcomeLabel.isHidden = false
welcomeLabel.text = "Hello, \(user.profile?.givenName ?? "User")!"
} else {
// User is signed out.
signInButton.isHidden = false
signOutButton.isHidden = true
welcomeLabel.isHidden = true
}
}
@objc func signOutButtonTapped() {
GIDSignIn.sharedInstance.signOut()
// Update the UI for the signed-out state.
updateUI(for: nil)
}
}
সাইলেন্ট সাইন-ইন পরীক্ষা করুন
সাইন ইন করার পর, অ্যাপটি সম্পূর্ণভাবে বন্ধ করে আবার চালু করুন। আপনি দেখবেন যে, বাটনটি ট্যাপ না করেই আপনি এখন স্বয়ংক্রিয়ভাবে সাইন ইন হয়ে গেছেন।
১০. আইডি টোকেনটি বুঝুন।
যদিও ব্যবহারকারীর নাম এবং ইমেল ব্যবহার করে UI ব্যক্তিগতকরণের জন্য GIDGoogleUser অবজেক্টটি সুবিধাজনক, SDK থেকে ফেরত আসা সবচেয়ে গুরুত্বপূর্ণ ডেটা হলো আইডি টোকেন।
এই কোডল্যাবটি JWT-এর বিষয়বস্তু পরীক্ষা করার জন্য একটি অনলাইন টুল ব্যবহার করে। একটি প্রোডাকশন অ্যাপে, আপনার এই আইডি টোকেনটি আপনার ব্যাকএন্ড সার্ভারে পাঠানো উচিত। আপনার সার্ভারকে অবশ্যই আইডি টোকেনটির অখণ্ডতা যাচাই করতে হবে এবং JWT ব্যবহার করে আরও অর্থবহ কিছু করতে হবে, যেমন আপনার ব্যাকএন্ড প্ল্যাটফর্মে একটি নতুন অ্যাকাউন্ট তৈরি করা বা ব্যবহারকারীর জন্য একটি নতুন সেশন স্থাপন করা।
JWT টোকেন অ্যাক্সেস এবং ডিকোড করুন
- আপনার অ্যাপটি চালু করুন।
- Xcode কনসোলটি খুলুন। আপনি একটি প্রিন্ট করা আইডি টোকেন দেখতে পাবেন। এটি দেখতে
eyJhbGciOiJSUzI1Ni ... Hecz6Wm4Qমতো হবে। - আইডি টোকেনটি কপি করুন এবং JWT ডিকোড করার জন্য jwt.io-এর মতো কোনো অনলাইন টুল ব্যবহার করুন।
ডিকোড করা JWT দেখতে এইরকম হবে:
{
"alg": "RS256",
"kid": "c8ab71530972bba20b49f78a09c9852c43ff9118",
"typ": "JWT"
}
{
"iss": "https://accounts.google.com",
"azp": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
"aud": "171291171076-rrbkcjrp5jbte92ai9gub115ertscphi.apps.googleusercontent.com",
"sub": "10769150350006150715113082367",
"email": "example@example.com",
"email_verified": true,
"at_hash": "JyCYDmHtzhjkb0-qJhKsMg",
"name": "Kimya",
"picture": "https://lh3.googleusercontent.com/a/ACg8ocIyy4VoR31t_n0biPVcScBHwZOCRaKVDb_MoaMYep65fyqoAw=s96-c",
"given_name": "Kimya",
"iat": 1758645896,
"exp": 1758649496
}
উল্লেখযোগ্য টোকেন ক্ষেত্র
ডিকোড করা আইডি টোকেনটিতে বিভিন্ন উদ্দেশ্যের ফিল্ড থাকে। নাম এবং ইমেলের মতো কিছু ফিল্ড সহজে বোঝা গেলেও, অন্যগুলো আপনার ব্যাকএন্ড সার্ভার যাচাইকরণের জন্য ব্যবহার করে।
নিম্নলিখিত ক্ষেত্রটি বোঝা বিশেষভাবে গুরুত্বপূর্ণ:
- সাব :
subফিল্ডটি ব্যবহারকারীর গুগল অ্যাকাউন্টের জন্য একটি অনন্য, স্থায়ী শনাক্তকারী। একজন ব্যবহারকারী তার প্রাথমিক ইমেল বা নাম পরিবর্তন করতে পারেন, কিন্তু তারsubআইডি কখনও পরিবর্তন হবে না। এই কারণে আপনার ব্যাকএন্ড ব্যবহারকারী অ্যাকাউন্টগুলোর জন্য প্রাইমারি কী হিসেবেsubফিল্ডটি একটি আদর্শ ভ্যালু।
আইডি টোকেন থেকে ব্যবহারকারীর তথ্য সংগ্রহ করলে টোকেনের সমস্ত ফিল্ডের অর্থ সম্পর্কে আরও বিস্তারিত জানা যায়।
১১. অ্যাপ চেক দিয়ে আপনার অ্যাপ সুরক্ষিত করুন
আপনার প্রোজেক্টের পক্ষ থেকে শুধুমাত্র আপনার অ্যাপই যেন গুগলের OAuth 2.0 এন্ডপয়েন্টগুলো অ্যাক্সেস করতে পারে, তা নিশ্চিত করার জন্য অ্যাপ চেক (App Check) চালু করার জন্য জোরালোভাবে সুপারিশ করা হচ্ছে। অ্যাপ চেক এই বিষয়টি যাচাই করার মাধ্যমে কাজ করে যে, আপনার ব্যাকএন্ড সার্ভিসগুলোতে পাঠানো অনুরোধগুলো একটি আসল এবং অপরিবর্তিত ডিভাইসে থাকা আপনার প্রকৃত অ্যাপ থেকেই আসছে।
এই বিভাগে দেখানো হয়েছে কীভাবে আপনার অ্যাপে অ্যাপ চেক (App Check) একীভূত করতে হয় এবং সিমুলেটরে ডিবাগিং ও আসল ডিভাইসে প্রোডাকশন বিল্ড চালানোর জন্য এটিকে কনফিগার করতে হয়।
কনসোল সেটআপ
আপনার অ্যাপ্লিকেশনে অ্যাপ চেক যুক্ত করার জন্য গুগল ক্লাউড এবং ফায়ারবেস কনসোলে একবার সেটআপ করতে হবে। এর জন্য গুগল ক্লাউড কনসোলে আপনার iOS OAuth ক্লায়েন্টের জন্য অ্যাপ চেক সক্রিয় করতে হবে, অ্যাপ চেক ডিবাগ প্রোভাইডারের জন্য একটি এপিআই কী তৈরি করতে হবে এবং আপনার গুগল ক্লাউড প্রজেক্টকে ফায়ারবেসের সাথে লিঙ্ক করতে হবে।
গুগল ক্লাউড কনসোলে অ্যাপ চেক সক্ষম করুন
- আপনার গুগল ক্লাউড প্রজেক্টের সাথে যুক্ত ক্লায়েন্টদের তালিকায় যান।
- আপনার iOS অ্যাপের জন্য তৈরি করা OAuth 2.0 ক্লায়েন্ট আইডিটি নির্বাচন করুন।
- iOS-এর জন্য Google Identity-এর নিচে অ্যাপ চেক চালু করুন

- সংরক্ষণ করুন- এ ক্লিক করুন।
একটি এপিআই কী তৈরি করুন
- আপনার গুগল ক্লাউড প্রজেক্টের এপিআই লাইব্রেরি পৃষ্ঠায় যান।
- সার্চ বারে Firebase App Check API লিখুন।

- Firebase App Check API-টি নির্বাচন করে সক্রিয় করুন।
- APIs & Services- এ যান এবং নেভিগেশন মেনু থেকে Credentials নির্বাচন করুন।
- পৃষ্ঠার শীর্ষে থাকা 'ক্রেডেনশিয়াল তৈরি করুন' নির্বাচন করুন।

- এই API Key-টির একটি নাম নির্ধারণ করুন।
- অ্যাপ্লিকেশন বিধিনিষেধের অধীনে iOS অ্যাপ নির্বাচন করুন।
- আপনার অ্যাপের বান্ডেল আইডেন্টিফায়ারটিকে একটি অনুমোদিত অ্যাপ্লিকেশন হিসেবে যুক্ত করুন।
- API বিধিনিষেধের অধীনে রেস্ট্রিক্ট কী নির্বাচন করুন।
- ড্রপ-ডাউন মেনু থেকে ফায়ারবেস অ্যাপ চেক এপিআই (Firebase App Check API) নির্বাচন করুন।
- তৈরি করুন নির্বাচন করুন।

- তৈরি হওয়া API কী-টি কপি করে রাখুন। পরবর্তী ধাপে আপনার এটি প্রয়োজন হবে।
আপনার গুগল ক্লাউড প্রকল্পে ফায়ারবেস যুক্ত করুন
- ফায়ারবেস কনসোলে যান।
- একটি Firebase প্রজেক্ট সেট আপ করে শুরু করুন নির্বাচন করুন ।
- গুগল ক্লাউড প্রকল্পে ফায়ারবেস যোগ করুন নির্বাচন করুন।

- ড্রপ-ডাউন থেকে একটি গুগল ক্লাউড প্রজেক্ট বেছে নিন এবং সাইন-আপ প্রক্রিয়াটি সম্পন্ন করুন।
- ফায়ারবেস যোগ করুন নির্বাচন করুন।
- আপনার Firebase প্রজেক্টটি প্রস্তুত হয়ে গেলে, প্রজেক্টটি খোলার জন্য 'Continue' নির্বাচন করুন।
ক্লায়েন্ট-সাইড কোড ইন্টিগ্রেশন
অ্যাপ চেকের জন্য গুগল ক্লাউড প্রজেক্টটি কনফিগার করা হয়ে গেলে, এটি চালু করার জন্য ক্লায়েন্ট-সাইড কোড লেখার সময় এসেছে। প্রোডাকশন এবং ডিবাগ এনভায়রনমেন্টে অ্যাটেস্টেশনের জন্য ব্যবহৃত প্রোভাইডার ভিন্ন হয়। একটি আসল ডিভাইসের প্রোডাকশন অ্যাপ তার সত্যতা প্রমাণ করার জন্য অ্যাপলের বিল্ট-ইন অ্যাপ অ্যাটেস্ট সার্ভিস ব্যবহার করে। তবে, যেহেতু আইওএস সিমুলেটর এই ধরনের অ্যাটেস্টেশন প্রদান করতে পারে না, তাই ডিবাগ এনভায়রনমেন্টের জন্য একটি বিশেষ ডিবাগ প্রোভাইডারের প্রয়োজন হয়, যেটিকে একটি এপিআই কী (API key) পাস করা হয়।
নিম্নলিখিত কোডটি একটি কম্পাইলার ডিরেক্টিভ ব্যবহার করে বিল্ড টাইমে স্বয়ংক্রিয়ভাবে সঠিক প্রোভাইডার নির্বাচন করার মাধ্যমে উভয় পরিস্থিতিই সামাল দেয়।
SwiftUI
- মূল অ্যাপ ফাইলটি খুলুন।
- import-গুলোর পরে এবং
@mainঅ্যাট্রিবিউটের আগে নিম্নলিখিতAppDelegateক্লাসটি সংজ্ঞায়িত করুন:
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
#if targetEnvironment(simulator)
// Configure for debugging on a simulator.
// TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
let apiKey = "YOUR_API_KEY"
GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
if let error {
print("Error configuring GIDSignIn debug provider: \(error)")
}
}
#else
// Configure GIDSignIn for App Check on a real device.
GIDSignIn.sharedInstance.configure { error in
if let error {
print("Error configuring GIDSignIn for App Check: \(error)")
} else {
print("GIDSignIn configured for App Check.")
}
}
#endif
return true
}
}
- প্রদত্ত কোডে
"YOUR_API_KEY"জায়গায় গুগল ক্লাউড কনসোল থেকে কপি করা এপিআই কী (API Key) বসান। - আপনার
Appstruct-এর ভিতরে,bodyভেরিয়েবলের ঠিক আগে নিম্নলিখিত লাইনটি যোগ করুন। এটি আপনার AppDelegate ক্লাসকে অ্যাপ লাইফসাইকেলের সাথে রেজিস্টার করে, যার ফলে এটি অ্যাপ লঞ্চ এবং অন্যান্য সিস্টেম ইভেন্টে সাড়া দিতে পারে:
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
আপনার মূল অ্যাপ ফাইলটি দেখতে এইরকম হওয়া উচিত:
import GoogleSignIn
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
#if targetEnvironment(simulator)
// Configure for debugging on a simulator.
// TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
let apiKey = "YOUR_API_KEY"
GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
if let error {
print("Error configuring GIDSignIn debug provider: \(error)")
}
}
#else
// Configure GIDSignIn for App Check on a real device.
GIDSignIn.sharedInstance.configure { error in
if let error {
print("Error configuring GIDSignIn for App Check: \(error)")
} else {
print("GIDSignIn configured for App Check.")
}
}
#endif
return true
}
}
@main
struct iOS_Sign_in_with_Google_App: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
GIDSignIn.sharedInstance.handle(url)
}
}
}
}
UIKit
- AppDelegate.swift খুলুন।
- অ্যাপ চেক ইনিশিয়ালাইজেশন অন্তর্ভুক্ত করার জন্য
application(_:didFinishLaunchingWithOptions:)মেথডটি আপডেট করুন:
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
#if targetEnvironment(simulator)
// Configure for debugging on a simulator.
// TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
let apiKey = "YOUR_API_KEY"
GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
if let error {
print("Error configuring GIDSignIn debug provider: \(error)")
}
}
#else
// Configure GIDSignIn for App Check on a real device.
GIDSignIn.sharedInstance.configure { error in
if let error {
print("Error configuring GIDSignIn for App Check: \(error)")
}
}
#endif
return true
}
- প্রদত্ত কোডে
"YOUR_API_KEY"জায়গায় গুগল ক্লাউড কনসোল থেকে কপি করা এপিআই কী (API Key) বসান।
আপনার AppDelegate.swift ফাইলটি দেখতে এইরকম হওয়া উচিত:
import GoogleSignIn
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
#if targetEnvironment(simulator)
// Configure for debugging on a simulator.
// TODO: Replace "YOUR_API_KEY" with the key from your Google Cloud project.
let apiKey = "YOUR_API_KEY"
GIDSignIn.sharedInstance.configureDebugProvider(withAPIKey: apiKey) { error in
if let error {
print("Error configuring GIDSignIn debug provider: \(error)")
}
}
#else
// Configure GIDSignIn for App Check on a real device.
GIDSignIn.sharedInstance.configure { error in
if let error {
print("Error configuring GIDSignIn for App Check: \(error)")
}
}
#endif
return true
}
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
var handled: Bool
handled = GIDSignIn.sharedInstance.handle(url)
if handled {
return true
}
// If not handled by this app, return false.
return false
}
// MARK: UISceneSession Lifecycle
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
func application(
_ application: UIApplication,
didDiscardSceneSessions sceneSessions: Set<UISceneSession>
) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
সিমুলেটরে অ্যাপটি পরীক্ষা করে দেখুন
- Xcode মেনু বারে, Product > Scheme > Edit Scheme- এ যান।
- ন্যাভিগেশন মেনু থেকে রান নির্বাচন করুন।
- আর্গুমেন্টস ট্যাবটি নির্বাচন করুন।
- 'Arguments Passed on Launch' বিভাগে, + নির্বাচন করুন এবং -FIRDebugEnabled যোগ করুন। এই লঞ্চ আর্গুমেন্টটি Firebase ডিবাগ লগিং সক্ষম করে।
- বন্ধ নির্বাচন করুন।

- সিমুলেটরে আপনার অ্যাপটি চালু করুন।
- এক্সকোড কনসোলে প্রিন্ট হওয়া অ্যাপ চেক ডিবাগ টোকেনটি কপি করুন।

- Firebase Console- এ আপনার প্রজেক্টে যান।
- ন্যাভিগেশন মেনুতে থাকা বিল্ড সেকশনটি প্রসারিত করুন।
- অ্যাপ চেক নির্বাচন করুন।
- অ্যাপস ট্যাবটি নির্বাচন করুন।
- আপনার অ্যাপের উপর মাউস রাখুন এবং তিন-বিন্দু মেনু আইকনটি নির্বাচন করুন।

- ডিবাগ টোকেন পরিচালনা নির্বাচন করুন।
- ডিবাগ টোকেন যোগ করুন নির্বাচন করুন।
- আপনার ডিবাগ টোকেনটির একটি নাম দিন এবং ভ্যালু হিসেবে আগে কপি করা ডিবাগ টোকেনটি পেস্ট করুন।
- আপনার টোকেনটি নিবন্ধন করতে সেভ নির্বাচন করুন।

- সিমুলেটরে ফিরে যান এবং সাইন ইন করুন।
কনসোলে মেট্রিকগুলো প্রদর্শিত হতে কয়েক মিনিট সময় লাগতে পারে। সেগুলো প্রদর্শিত হয়ে গেলে, আপনি দুটি জায়গার যেকোনো একটিতে ভেরিফাইড রিকোয়েস্টের সংখ্যা বৃদ্ধি দেখে অ্যাপ চেক ঠিকমতো কাজ করছে কিনা তা নিশ্চিত হতে পারেন:
- Firebase Console-এর App Check সেকশনের APIs ট্যাবের অধীনে।

- গুগল ক্লাউড কনসোলে আপনার OAuth ক্লায়েন্টের সম্পাদনা পৃষ্ঠায়।

আপনার অ্যাপের অ্যাপ চেক মেট্রিক্স নিরীক্ষণ করার পর এবং বৈধ অনুরোধগুলি যাচাই করা হচ্ছে তা নিশ্চিত করার পরে, আপনার অ্যাপ চেক এনফোর্সমেন্ট সক্রিয় করা উচিত। একবার সক্রিয় করা হলে, অ্যাপ চেক সমস্ত যাচাইবিহীন অনুরোধ প্রত্যাখ্যান করে, যা নিশ্চিত করে যে শুধুমাত্র আপনার আসল অ্যাপের ট্র্যাফিকই আপনার প্রকল্পের পক্ষ থেকে গুগলের OAuth 2.0 এন্ডপয়েন্টগুলি অ্যাক্সেস করতে পারবে।
১২. অতিরিক্ত সম্পদ
অভিনন্দন!
আপনি একটি OAuth 2.0 iOS ক্লায়েন্ট কনফিগার করেছেন, একটি iOS অ্যাপে ‘Sign in with Google’ বাটন যোগ করেছেন, বাটনটির চেহারা কাস্টমাইজ করার পদ্ধতি শিখেছেন, একটি JWT ID টোকেন ডিকোড করেছেন এবং আপনার অ্যাপের জন্য ‘App Check’ সক্রিয় করেছেন।
এই লিঙ্কগুলো আপনাকে পরবর্তী পদক্ষেপের জন্য সাহায্য করতে পারে:
- iOS-এর জন্য গুগল সাইন-ইন কীভাবে শুরু করবেন
- iOS রিপোজিটরির জন্য গুগল সাইন-ইন
- একটি গুগল আইডি টোকেন যাচাই করুন
- iOS-এ গুগল সাইন-ইন এর জন্য অ্যাপ চেক ব্যবহার শুরু করুন
- অ্যাক্সেস টোকেন বাতিল করা এবং অ্যাপটি সংযোগ বিচ্ছিন্ন করা
- গুগল ক্লাউড প্রজেক্ট সম্পর্কে আরও জানুন
- গুগল পরিচয় প্রমাণীকরণ পদ্ধতি
- অ্যাপ চেক প্রয়োগ সক্ষম করুন