I am currently using the ability to log in with my Instagram account using ASWebAuthenticationSession and it is not working!
I filled in the URL directly and there was no problem on the web, but when I run it in SwiftUI in Xcode, it doesn't work and Error: The operation couldn’t be completed. (com.apple.AuthenticationServices.WebAuthenticationSession error 2.) I get this error.
I was told that I need a custom scheme to return to mobile, but the Instagram redirect URL says no custom scheme.
What should I do?
IDs and URLs are placed under assumption.
I have no idea since this is my first implementation. Should I send the scheme URL from the website to mobile once using Django or something else?
import SwiftUI
import AuthenticationServices
struct InstagramLoginView: View {
@State private var authSession: ASWebAuthenticationSession?
@State private var token: String = ""
@State private var showAlert: Bool = false
@State private var alertMessage: String = ""
var body: some View {
VStack {
Text("Instagram Login")
.font(.largeTitle)
.padding()
Button(action: {
startInstagramLogin()
}) {
Text("Login with Instagram")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
if !token.isEmpty {
Text("Token: \(token)")
.padding()
}
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Error"), message: Text(alertMessage), dismissButton: .default(Text("OK")))
}
}
func startInstagramLogin() {
let clientID = "XXXXXXXXXX" // Instagram client ID
let redirectURI = "https://example.com" // Instagram Redirect URI
guard let authURL = URL(string: "https://api.instagram.com/oauth/authorize?client_id=\(clientID)&redirect_uri=\(redirectURI)&scope=user_profile,user_media&response_type=code") else {
print("Invalid URL")
return
}
authSession = ASWebAuthenticationSession(url: authURL, callbackURLScheme: "customscheme") { callbackURL, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let callbackURL = callbackURL else {
print("Invalid callback URL")
return
}
if let code = URLComponents(string: callbackURL.absoluteString)?.queryItems?.first(where: { $0.name == "code" })?.value {
print("Authorization code: \(code)")
getInstagramAccessToken(authCode: code)
}
}
authSession?.start()
}
func getInstagramAccessToken(authCode: String) {
let tokenURL = "https://api.instagram.com/oauth/access_token"
var request = URLRequest(url: URL(string: tokenURL)!)
request.httpMethod = "POST"
let clientID = "XXXXXXXXXXXX"
let clientSecret = "XXXXXXXXXXXXXX" // Instagram clientSecret
let redirectURI = "https://example.com/"
let params = "client_id=\(clientID)&client_secret=\(clientSecret)&grant_type=authorization_code&redirect_uri=\(redirectURI)&code=\(authCode)"
request.httpBody = params.data(using: .utf8)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error.localizedDescription)")
return
}
guard let data = data else {
print("No data")
return
}
if let jsonResponse = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let accessToken = jsonResponse["access_token"] as? String {
print("Access Token: \(accessToken)")
// ここでアクセストークンを使用してInstagram APIにアクセスする
} else {
print("Failed to get access token")
}
}.resume()
}
}
#Preview {
InstagramLoginView()
}