FaceID window behaviour - swift

After unsuccessful attempt of FaceId for two times, pop up window does not auto close. Is there any handler to auto close the FaceId after all unsuccessful attempts or any handler to control the FaceId pop up.
The behaviour of pop up is different than touchId.
Please help.
Code is below:-
func authentication() {
let localAuthenticationContext = LAContext()
localAuthenticationContext.localizedFallbackTitle = “Failed Authentication”
var authError: NSError?
if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
localAuthenticationContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString) { success, error in
if success {
print("Authentication Successful”);
} else {
print("Authentication failure");
guard let error = error else {
return
}
let errorMessage = self.errorMessageForFails(errorCode: error._code)
print(errorMessage);
}
}
} else {
guard let error = authError else {
return
}
let errorMessage = self.errorMessageForFails(errorCode: error._code)
display(errorMessage)
}
}

Related

Bug while error handling Firebase Authentication with swiftUI

This is my AuthViewModel:
#Published var userSession: User?
#Published var currentUser: AppUser?
#Published var signupError: Error?
#Published var loginError: Error?
static let shared = AuthViewModel()
init() {
self.userSession = Auth.auth().currentUser
fetchUser()
}
func fetchUser() {
guard let uid = userSession?.uid else { return }
USER_COLLECTION.document(uid).getDocument { snapshot, _ in
guard let user = try? snapshot?.data(as: AppUser.self) else { return }
self.currentUser = user
}
}
func registerUser(withEmail email: String, password: String) {
Auth.auth().createUser(withEmail: email, password: password) { result, error in
if let error = error {
self.signupError = error
print("error")
return
}
guard let user = result?.user else { return }
let data: [String: Any] = ["uid": user.uid, "email": user.email ?? ""]
USER_COLLECTION.document(user.uid).setData(data) { err in
self.userSession = user
self.fetchUser()
}
}
}
func login(withEmail email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { result, error in
if let error = error {
self.loginError = error
return
}
guard let user = result?.user else { return }
self.userSession = user
self.fetchUser()
}
}
I have 2 published variables which are updated every time there is an error in their respective functions. However, when I click the 'sign up' button the first time with invalid credentials, I don't get an alert. I have to click it the second time to see the alert. Attached below is the code from the sign up view SwiftUI button with action and label. The same applies to the login view.
Button {
authViewModel.registerUser(withEmail: email, password: password)
print("called")
if let error = authViewModel.signupError {
alertTitle = "Error signing up!"
alertMessage = error.localizedDescription
alertShowing = true
print(alertShowing)
}
print(alertShowing)
} label: {
CustomAuthButton(text: "Sign Up")
}
Below is the code attached to the sign up view (navigation view):
.alert(alertTitle, isPresented: $alertShowing) {
Button("OK") {
authViewModel.signupError = nil
}
} message: {
Text(alertMessage)
}
Attached below is the code for registering a user. I'll put the result of those print statements below.
Auth.auth().createUser(withEmail: email, password: password) { result, error in
if let error = error {
DispatchQueue.main.async {
self.signupError = error
print("error")
return
}
}
called
false
2022-07-06 12:59:54.424510+0530 InfoMax[62528:2751506] [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics
error
As you can see, error is being printed late. When I tap the button the second time, it is printed before, so I get the alert.

How to have code inside of a guard else statement in swift?

I have the following code:
#IBAction func loginTapped(_ sender: Any) {
let error = validateFieldsSignIn()
if error != nil {
showErrorSignIn(error!)
} else {
guard let emailsignin = emailSignIn?.text!.trimmingCharacters(in: .whitespacesAndNewlines),
let passwordsignin = passwordSignIn?.text!.trimmingCharacters(in: .whitespacesAndNewlines) else {
return showErrorSignIn("Fill in all fields")
}
Auth.auth().signIn(withEmail: emailsignin, password: passwordsignin) { (user, error) in
if error != nil {
print("There was an error")
self.errorLabel3.text = "Invalid username or password"
self.errorLabel3.alpha = 1
} else {
self.transitionToHome()
}
}
}
}
Although unless the fields aren't filled in the else statement gets triggered and the error label says fill in all fields, essential the code that is getting triggered is this:
else {
return showErrorSignIn("Fill in all fields")
}
I tried putting the Auth.auth().signIn() inside the else block although I got the following error:
Variable declared in 'guard' condition is not usable in its body
How do I fix this error message?

Getting an error when implementing drop support for my Mac application

I'm trying to get the URL of a web page when it's dragged into my application view. I'm using the code below as the DropDelegate.
func performDrop(info: DropInfo) -> Bool {
guard let itemProvider = info.itemProviders(for: ["public.url"]).first else {
return false
}
guard itemProvider.canLoadObject(ofClass: URL.self) else {
return false
}
_ = itemProvider.loadObject(ofClass: URL.self) {url, _ in
if let url = url {
DispatchQueue.main.async {
do {
try self.store.urlToOpen = url.absoluteString
} catch {
}
}
}
}
return true
}
The error I'm getting is:
Could not instantiate class NSURL. Error: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive
I'm not sure what's going on and how to fix this. Any ideas?
Here is working solution. Tested with Xcode 12 / macOS 10.15.5
_ = itemProvider.loadDataRepresentation(forTypeIdentifier: "public.url") {url, _ in
if let data = data,
let path = String(bytes: data, encoding: .utf8),
let url = URL(string: path) {
DispatchQueue.main.async {
do {
try self.store.urlToOpen = url.absoluteString
} catch {
}
}
}
}

Is there a way to use Firebase with a ShareExtension without AppGroups

I'm setting up a shareExtension in iOS and want to use the FirebaseSDK to upload data direct instead of using AppGroups. This works as expected, but after 1 hour the UserToken get's invalidated and i can't reach the Firestore Backend anymore.
I'm using the FirebaseSDK (6.2.0) and enabled Keychain sharing to access the current signedIn User. I have the same Google-Plist in the MainApp and the shareExtension. The data gets also uploaded correctly from the shareExtension and was also updated via the snapshotListener in the MainApp.
Relevant code in the MainApp
lazy var db = Firestore.firestore()
//TEAMID form the Apple Developer Portal
let accessGroup = "TEAMID.de.debug.fireAuthExample"
override func viewDidLoad() {
super.viewDidLoad()
do {
try Auth.auth().useUserAccessGroup("\(accessGroup)")
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
guard let user = Auth.auth().currentUser else {
self.statusLabel.text = "user get's lost"
return
}
statusLabel.text = "UserID: \(user.uid)"
// Do any additional setup after loading the view.
db.collection("DummyCollection").addSnapshotListener { (querySnapshot, error) in
if let err = error {
print(err.localizedDescription)
}
guard let snapshot = querySnapshot else {
return
}
DispatchQueue.main.async {
self.dbCountLabel.text = "\(snapshot.count)"
}
}
}
func signIN(){
// https://firebase.google.com/docs/auth/ios/single-sign-on
do {
try Auth.auth().useUserAccessGroup("\(accessGroup)")
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
Auth.auth().signInAnonymously { (result, error) in
if let err = error{
print(err.localizedDescription)
return
}
print("UserID: \(Auth.auth().currentUser!.uid)")
}
}
}
}
Code in the shareExtension:
override func viewDidLoad() {
super.viewDidLoad()
if FirebaseApp.app() == nil {
FirebaseApp.configure()
}
do {
try Auth.auth().useUserAccessGroup(accessGroup)
} catch let error as NSError {
print("Error changing user access group: %#", error)
}
tempUser = Auth.auth().currentUser
if tempUser != nil {
userIDLabel.text = "UserID: \(tempUser!.uid)"
doneButton.isEnabled = true
db.collection("DummyCollection").addSnapshotListener { (querySnapshot, error) in
if let err = error {
print(err.localizedDescription)
}
guard let snapshot = querySnapshot else {
return
}
DispatchQueue.main.async {
self.dataCountLabel.text = "\(snapshot.count)"
}
}
} else {
// No user exists in the access group
self.navigationItem.title = "No User"
}
}
I expect that this should be possible, but the Token gets somehow invalid in the MainApp and i could not reach the Firestore backend.
6.2.0 - [Firebase/Auth][I-AUT000003] Token auto-refresh re-scheduled in 01:00 because of error on previous refresh attempt.
6.2.0 - [Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: An internal error has occurred, print and inspect the error details for more information.
Answering my own question: This should be fixed in the next release (Firebase 6.4.0) Details can be found in this PR 3239.

Value of type 'error' has no member 'userinfo'

My code is as follows:
if signupMode {
let user = PFUser()
user.username = emailTextField.text
user.email = emailTextField.text
user.password = passwordTextField.text
user.signUpInBackground(block: {
(success, error) in
if error != nil {
let displayErrorMessage = "Please try again later"
if let errorMessage = error.UserInfo["error"]? as String {
displayErrorMessage = errorMessage
}
self.createAlert(title: "Error", message: "Parse Error")
}
I just keep getting the error
"value of type 'error' has no member 'userinfo"
What can I do to fix this? I'm using Xcode 8
By your snipped it can't be determined what error is and wether it should have a member called UserInfo. Please provide more code...
I assume it is an NSError? In this case it would be error.userInfo as member name. (watch the casing)
Other than that your code will fail compiling because you declare let displayErrorMessage but in the if make an assignment to it. You would need to change it to var displayErrorMessage to be able to do that.
Try this:
user.signUpInBackgroundWithBlock {
(succeeded: Bool!, error: NSError!) -> Void in
if error == nil {
// Perform a segue, show a message or whatever you want
} else {
let errorString = error.userInfo["error"] as NSString
// Show the errorString somewhere and let the user try again.
}
}
If you're still getting this error, try this code. Force unwrap error as NSError.
if let errorMessage = (error! as NSError).userInfo["error"] as? String {
displayErrorMessage = errorMessage
}