Swift 4: Unable to get User Profile image from Facebook - ios

I am using firebase Facebook auth. User is able to successfully login I am able to get user profile image from firebase after Facebook login but I need customized image for a better quality. I am unable to get user profile image using this code which uses UserProfile class. Although similar code for android works fine.
My Custom Facebook Button Code. Written in class SignUpFirst.
#IBAction func facebookLogin(_ sender: AnyObject) {
let loginManager = LoginManager()
loginManager.logIn([ .publicProfile,.email], viewController: self) { loginResult in
switch loginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
//print("Logged in! \(accessToken)")
let credential = FacebookAuthProvider.credential(withAccessToken: accessToken.authenticationToken)
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
//show error if failed
print(error.localizedDescription)
return
}
checkUser(firebaseUser: user!)
}
}
}
}
Trying to get user profile image in class SignUpSecond.
UserProfile.current?.imageURLWith(UserProfile.PictureAspectRatio.normal, size: CGSize(width: 10.0, height: 10.0))
But this code is returning nil here. I have also tried adding this code in success of Facebooklogin button it was still returning nil. What is the solution.

After successful login, you would get token but not profile.
It means UserProfile.current still nil.
you must load profile. You can reference similair question
use https://graph.facebook.com/{use-id}/picture?type=square&width=10&height=10 to get avatar url directly. example:
https://graph.facebook.com/1410901795642099/picture?type=square&width=10&height=10

Related

Redirect to another view after successful login?

Currently I am trying to redirect user to dashboard after checking if they have valid credentials. This is my code below. I've tried creating variables (bools) to check for this condition, however, variables don't save updated value in completion handler
#IBAction func loginPressed(_ sender: UIButton){ //login works
guard let email = enterEmailTextField.text else {return}
guard let password = enterPasswordTextField.text else {return}
let loginModel = LoginModel(username: email, password: password)
APIManager.shareInstance.loginUserAPI(login: loginModel) { (result) in
switch result{
case .success(let json):
print(json as AnyObject)
case .failure(let err):
print(err.localizedDescription)
}
}
}
So my question is, how do I "extract" some type of information when the user logs in (confirming valid credentials) and then redirect to another view?
Thank you in advance!

Sign in with Apple - ASAuthorizationAppleIDProvider already signed in but notfound

recently I'm learning SiwA on
https://fluffy.es/sign-in-with-apple-tutorial-ios/
I tried to learn step-by step, however, I met some wired problem when I used "ASAuthorizationAppleIDProvider". I have saved the userID in local, but it returns notfound when using ASAuthorizationAppleIDProvider. I also delete the Apple ID used before in
Settings > Apple ID > Password & Security > Apps Using your Apple ID
But it stills return notfound when I re-login. Here is my code.
extension LoginViewController: ASAuthorizationControllerDelegate{
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
print("something bad", error)
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential{
UserDefaults.standard.set(appleIDCredential.user, forKey: appleAccount.userID)
}
}
}
if let userID = UserDefaults.standard.string(forKey: appleAccount.userID) {
ASAuthorizationAppleIDProvider().getCredentialState(forUserID: userID, completion: {
credentialState, error in
print(userID)
switch(credentialState){
case .authorized:
print("user remain logged in, proceed to another view")
self.performSegue(withIdentifier: "LoginToUserSegue", sender: nil)
case .revoked:
print("user logged in before but revoked")
case .notFound:
print("user haven't log in before")
default:
print("unknown state")
}
})
}
It indeed print userID so userID is not nil. But seems it's not match with the Apple ID so it shows notfound? Here is the error
[core] Credential State request returned with error: Error Domain=AKAuthenticationError Code=-7073 "(null)"
The problem is caused by simulator, if we change to device, there is no such problem. See reference:
failed to get credential.state and getCredentialStateForUserID

Use of unresolved identifer - IOS Swift3

I am at my wits end here, I have been working on this for days and cannont seem to resolve this issue. I am relitivly new to the coding world, so I am sure this is a rookie mistake, but I just can't afford to waste any more time on this, its been a week almost.
I am writing in XCode 8.3, Swift 3. I am following tutorials to the letter from Auth0's website. Before I entered the code I am pasting below, my app would complie, but it would not work. Auth0 said I was mising this code.
I am receiving the following error: Use of unresolved identifier 'accessToken' I have no other errors or red !'s but this will not go away. I have tried moving the code around, that doesn't work. I have tried let, else, if statements, that doesn't work. I have spent mind numbing hours googling, and still I just can't seem to grasp what I am doing wrong.
Here is the code:
import UIKit
import Lock
import Auth0
import SimpleKeychain
class HomeViewController: UIViewController {
// MARK: - IBAction
#IBAction func showLoginController(_ sender: UIButton) {
Lock
.classic()
.withOptions {
$0.oidcConformant = true
$0.scope = "openid profile"
}
.onAuth { credentials in
let keychain = A0SimpleKeychain(service: "Auth0")
guard let accessToken = credentials.accessToken else { return }
keychain.setString(accessToken, forKey: "access_token")
self.showSuccessAlert(accessToken)
}
.present(from: self)
Auth0
.authentication()
.userInfo(withAccessToken: accessToken)
.start { result in
switch(result) {
case .sucess(let profile): break
case .failure(let error): break
}
}
Auth0
.webAuth()
.scope("openid profile")
.audience("https://mycompany.auth0.com/userinfo")
.start {
switch $0 {
case .failure(let error):
// Handle the error
print("Error: \(error)")
case .success(let credentials):
// Do something with credentials e.g.: save them.
// Auth0 will automatically dismiss the hosted login page
print("Credentials: \(credentials)")
}
}
Auth0
.webAuth()
.scope("openid profile offline_access")
.start {
switch $0 {
case .failure(let error):
// Handle the error
print("Error: \(error)")
case .success(let credentials):
guard let accessToken = credentials.accessToken, let refreshToken = credentials.refreshToken else { return }
let keychain = A0SimpleKeychain(service: "Auth0")
keychain.setString(accessToken, forKey: "access_token")
keychain.setString(refreshToken, forKey: "refresh_token")
}
}
}
// MARK: - Private
fileprivate func showSuccessAlert(_ accessToken: String) {
let alert = UIAlertController(title: "Success", message: "accessToken: \(accessToken)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
Strategies for Debugging Swift Code:
Thoroughly investigate LLDB debugger to see what happened
Read through existing code (all .swift files that you wrote code in) to check for any spelling errors, etc.
Open a new Xcode project and run each .swift file to pinpoint where the error is and/or use breakpoints in your existing Xcode project
Enable zombies
Code pesticides :P
Good luck with the rest of your project!

What is the value for Set<Permission> with FacebookLogin in iOS (Swift)

I am using the new Swift SDK FacebookLogin for a custom login button and following the guidelines provided by Facebook for Developers (which is already out of date!)
Question: what values do I provide for grantedPermissions (ie, Set), declinedPermissions (ie, Set), and token (ie, AccessToken)?
Thanks
import FacebookCore
import FacebookLogin
let facebookLogin = LoginManager()
facebookLogin.logIn([.publicProfile], viewController: self) { LoginResult in
switch LoginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(grantedPermissions: Set<Permission>, declinedPermissions: Set<Permission>, token: AccessToken):
print("Logged in!")
}
}
You can pass result's declinedPermissions and grantedPermissions .
result which you got with successful login
case .success(grantedPermissions:result?.token.permissions, declinedPermissions: result?.token.declinedPermissions, token: result?.token.tokenString):

Swift: Facebook SDK, checking missing permissions after successful login

I am trying to check for missing permissions once a user has successfully logged into the app.
func checkUserPermission()
{
let loginResult: FBSDKLoginManagerLoginResult = FBSDKLoginManagerLoginResult()
var missingPermissions: [String] = []
if !loginResult.grantedPermissions.containsObject("public_profile")
{
missingPermissions.append("public_profile")
}
if !loginResult.grantedPermissions.containsObject("email")
{
missingPermissions.append("email")
}
if !loginResult.grantedPermissions.containsObject("user_friends")
{
missingPermissions.append("user_friends")
}
if !loginResult.grantedPermissions.containsObject("user_likes")
{
missingPermissions.append("user_likes")
}
println(missingPermissions)
}
This function is ran when the app state changes to make sure I have all the permissions I need to make the app functional.
I am currently receiving this error "fatal error: unexpectedly found nil while unwrapping an Optional value" but I cant seem to understand why. If the "FBSDKAccessToken.currentAccessToken()" is set then in theory the permissions should be set as well.
Found the issue, I assumed let loginResult: FBSDKLoginManagerLoginResult = FBSDKLoginManagerLoginResult() will store the permissions granted but to get the active permissions of the current logged in user you will have to rely on FBSDKAccessToken. So replacing loginResult with
let loginResult: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken()
Should fix the issue. Also grantedPermissions will be changed to permissions. Here is the working function:
func checkUserPermission()
{
let loginResult: FBSDKAccessToken = FBSDKAccessToken.currentAccessToken()
var missingPermissions: [String] = []
if !loginResult.permissions.containsObject("public_profile")
{
missingPermissions.append("public_profile")
}
if !loginResult.permissions.containsObject("email")
{
missingPermissions.append("email")
}
if !loginResult.permissions.containsObject("user_friends")
{
missingPermissions.append("user_friends")
}
if !loginResult.permissions.containsObject("user_likes")
{
missingPermissions.append("user_likes")
}
println(missingPermissions)
//let login: FBSDKLoginManager = FBSDKLoginManager()
//login.logInWithReadPermissions([""], handler: <#FBSDKLoginManagerRequestTokenHandler!##(FBSDKLoginManagerLoginResult!, NSError!) -> Void#>)
//login.loginw
}
With the (current) version 0.2.0 of Facebook SDK for Swift, this works:
func loginButtonClicked() {
let loginManager = LoginManager()
loginManager.logIn([ .publicProfile, .email ], viewController: self) { loginResult in
switch loginResult {
case .failed(let error):
print(error)
case .cancelled:
print("User cancelled login.")
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
print("Logged in!")
// Check for access to email address
if declinedPermissions.contains(FacebookCore.Permission.init(name: "email")) {
print("Email access declined")
}
}
}
}

Resources