0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WebViewの実装について

Posted at

WebViewとは

参考にした記事

WebView.swift

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let url: String
    
    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        guard let url = URL(string: url) else {
            return
        }
        let request = URLRequest(url: url)
        uiView.load(request)
    }
}


ContentView.swift

※コード全体の仕組みとしてはGoogleのログインが出来たらアカウントの情報やアイコンと一緒にWebViewも表示されるようになっています。

import SwiftUI
import Firebase
import FirebaseAuth
import GoogleSignIn

struct ContentView: View {
    private let url = "https://www.apple.com"
    
    @State private var isSignedIn = false
    @State private var userName: String = ""
    @State private var userEmail: String = ""
    @State private var profileImage: UIImage? = nil

    var body: some View {
        VStack(spacing: 20) {
            //MARK: -  ログイン後
            if isSignedIn {
                VStack {
                    if let profileImage = profileImage {
                        Image(uiImage: profileImage)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 100, height: 100)
                            .clipShape(Circle())
                            .overlay(Circle().stroke(Color.blue, lineWidth: 2))
                            .shadow(radius: 5)
                    }

                    Text("Welcome, \(userName)")
                        .font(.title2)
                        .bold()

                    Text(userEmail)
                        .font(.subheadline)
                        .foregroundColor(.gray)

                    Button("Sign Out") {
                        signOut()
                    }
                    .frame(width: 200, height: 50)
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(10)
                    
                    WebView(url: url)//ログイン成功したらWebViewが表示される
                }
            } else {
                VStack {
                    GoogleSignInButton {
                        signInWithGoogle()
                    }
                }
            }
        }
        .padding()
        .onAppear {
            restoreSession()
        }
    }

    private func signInWithGoogle() {
        guard let clientID = FirebaseApp.app()?.options.clientID else { return }

        let config = GIDConfiguration(clientID: clientID)
        guard let rootViewController = UIApplication.shared.connectedScenes
            .compactMap({ $0 as? UIWindowScene })
            .flatMap({ $0.windows })
            .first(where: { $0.isKeyWindow })?.rootViewController else {
            print("Unable to get root view controller.")
            return
        }

        GIDSignIn.sharedInstance.signIn(withPresenting: rootViewController) { result, error in
            if let error = error {
                print("Google Sign-In failed: \(error.localizedDescription)")
                return
            }

            guard let user = result?.user,
                  let idToken = user.idToken?.tokenString else { return }

            let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: user.accessToken.tokenString)
            Auth.auth().signIn(with: credential) { authResult, error in
                if let error = error {
                    print("Firebase Authentication failed: \(error.localizedDescription)")
                } else {
                    self.isSignedIn = true
                    self.userName = user.profile?.name ?? "No Name"
                    self.userEmail = user.profile?.email ?? "No Email"
                    
                    // Load profile image
                    if let imageURL = user.profile?.imageURL(withDimension: 200) {
                        loadProfileImage(from: imageURL)
                        saveSession(userName: self.userName, userEmail: self.userEmail, profileImageURL: imageURL)
                    }
                }
            }
        }
    }

    private func signOut() {
        do {
            try Auth.auth().signOut()
            GIDSignIn.sharedInstance.signOut()
            clearSession()
            self.isSignedIn = false
            self.userName = ""
            self.userEmail = ""
            self.profileImage = nil
        } catch {
            print("Failed to sign out: \(error.localizedDescription)")
        }
    }

    private func loadProfileImage(from url: URL) {
        URLSession.shared.dataTask(with: url) { data, _, error in
            if let error = error {
                print("Failed to load profile image: \(error.localizedDescription)")
                return
            }

            if let data = data, let image = UIImage(data: data) {
                DispatchQueue.main.async {
                    self.profileImage = image
                }
            }
        }.resume()
    }

    // MARK: - Session Management
    private func saveSession(userName: String, userEmail: String, profileImageURL: URL) {
        UserDefaults.standard.setValue(userName, forKey: "userName")
        UserDefaults.standard.setValue(userEmail, forKey: "userEmail")
        UserDefaults.standard.setValue(profileImageURL.absoluteString, forKey: "profileImageURL")
        UserDefaults.standard.setValue(true, forKey: "isSignedIn")
    }

    private func restoreSession() {
        let defaults = UserDefaults.standard
        if defaults.bool(forKey: "isSignedIn") {
            self.isSignedIn = true
            self.userName = defaults.string(forKey: "userName") ?? ""
            self.userEmail = defaults.string(forKey: "userEmail") ?? ""
            
            if let imageURLString = defaults.string(forKey: "profileImageURL"),
               let imageURL = URL(string: imageURLString) {
                loadProfileImage(from: imageURL)
            }
        }
    }

    private func clearSession() {
        let defaults = UserDefaults.standard
        defaults.removeObject(forKey: "userName")
        defaults.removeObject(forKey: "userEmail")
        defaults.removeObject(forKey: "profileImageURL")
        defaults.setValue(false, forKey: "isSignedIn")
    }
}

// MARK: - Google Sign-In Button
struct GoogleSignInButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            HStack {
                Image(systemName: "g.circle.fill")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 30, height: 30)
                    .foregroundColor(.white)

                Text("Sign in with Google")
                    .fontWeight(.semibold)
                    .font(.system(size: 18))
            }
            .frame(width: 250, height: 50)
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(25)
        }
        .shadow(radius: 5)
    }
}

#Preview {
    ContentView()
}

WebViewを使用している箇所

if let profileImage = profileImage{ } の内部となっています

                VStack {
                    if let profileImage = profileImage {
                        Image(uiImage: profileImage)
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(width: 100, height: 100)
                            .clipShape(Circle())
                            .overlay(Circle().stroke(Color.blue, lineWidth: 2))
                            .shadow(radius: 5)
                    }

                    Text("Welcome, \(userName)")
                        .font(.title2)
                        .bold()

                    Text(userEmail)
                        .font(.subheadline)
                        .foregroundColor(.gray)

                    Button("Sign Out") {
                        signOut()
                    }
                    .frame(width: 200, height: 50)
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(10)
                    
                    WebView(url: url)//ログイン成功したらWebViewが表示される
                }

Googleのログインボタンを作成しているコード

// MARK: - Google Sign-In Button
struct GoogleSignInButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            HStack {
                Image(systemName: "g.circle.fill")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 30, height: 30)
                    .foregroundColor(.white)

                Text("Sign in with Google")
                    .fontWeight(.semibold)
                    .font(.system(size: 18))
            }
            .frame(width: 250, height: 50)
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(25)
        }
        .shadow(radius: 5)
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?