Swift: "NSCocoaErrorDomain Code=134092" when executing CNSaveRequest of Contact Store - swift

I'm writing a command line program with Swift Package Manager that uses Contacts API to automatically add phonetic names for the contacts. However, I found I was unable to do so for contacts that has notes. First, when I was trying to enumerate the contacts, there is a strange error output:
2023-01-22 18:58:36.085525+0800 PhoneticNames[18591:98356] [core] Attempted to register account monitor for types client is not authorized to access: {(
"com.apple.account.CardDAV",
"com.apple.account.Exchange",
"com.apple.account.LDAP"
)}
2023-01-22 18:58:36.085580+0800 PhoneticNames[18591:98356] [accounts] CNAccountCollectionUpdateWatcher 0x6000003ccc40: Store registration failed: Error Domain=com.apple.accounts Code=7 "(null)"
2023-01-22 18:58:36.085606+0800 PhoneticNames[18591:98356] [accounts] CNAccountCollectionUpdateWatcher 0x6000003ccc40: Update event received, but store registration failed. This event will be handled, but the behavior is undefined.
2023-01-22 18:58:36.136236+0800 PhoneticNames[18591:98344] [api] Attempt to read notes by an unentitled app
According to this document, I need to add the notes entitlement only if I was requesting the note field with CNContactNoteKey. However, I was not requesting it and I still get that "Attempt to read notes by an unentitled app" error.
Here is my code for enumerating the contacts:
let keys: [CNKeyDescriptor] = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactFormatter.descriptorForRequiredKeys(for: .phoneticFullName)]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
fetchRequest.mutableObjects = true
do {
try store.enumerateContacts(with: fetchRequest) { (contact, stop) in
contacts.append(contact.mutableCopy() as! CNMutableContact)
}
} catch {
print("unable to list contacts. \(error)")
}
And this is how I update the contacts later:
let saveRequest = CNSaveRequest()
contact.phoneticFamilyName = phoneticFamilyName
contact.phoneticMiddleName = phoneticMiddleName
contact.phoneticGivenName = phoneticGivenName
saveRequest.update(contact)
do {
try store.execute(saveRequest)
} catch {
print("Fail to execute store request: \(error)")
}
This code works as expected for contacts without the note field. But for contact with a non-empty note field, the saveRequest fails and outputs the following error:
2023-01-22 18:58:36.197026+0800 PhoneticNames[18591:98344] [error] error: Unhandled error occurred during faulting: Error Domain=NSCocoaErrorDomain Code=134092 "(null)" ({
})
CoreData: error: Unhandled error occurred during faulting: Error Domain=NSCocoaErrorDomain Code=134092 "(null)" ({
})
I am using Swift 5.7, Xcode 14.2, macOS 13.1. I looked for all the documents but couldn't find anything about NSCocoaErrorDomain Code 134092.
I shouldn't receive the error "Attempt to read notes by an unentitled app" when I am not requesting notes. And I should be able to successfully execute the saveRequest that doesn't modify the note field. Does anyone knows how these error comes?

Related

Firebase Phone Authentication works on Simulator but not phone

I finally decided its time for testflight with my app. Authentication works perfectly in the simulator. I've tried it with test numbers (works great), I've tried it with my phone (sends verification code), and I've tried it with my parents phone (a device that has never been set up with my firebase) and it worked great.
As soon as I set it up on my device and tried to authenticate the same way, I encountered an error
here is the very simple code I took straight from firebase docs
public func startAuth(phoneNumber: String, completion: #escaping (Bool) -> Void) {
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { [weak self] verificationId, error in
guard error == nil else {
print("error verifying phone numer, Error: \n\(error!)")
completion(false)
return
}
self?.verificationId = verificationId
completion(true)
}
}
When running in the simulator, it works great, when running on my phone, I get this error:
error verifying phone numer, Error:
Error Domain=FIRAuthErrorDomain Code=17999 "An internal error has occurred, print and inspect the error details for more information." UserInfo={FIRAuthErrorUserInfoNameKey=ERROR_INTERNAL_ERROR, NSLocalizedDescription=An internal error has occurred, print and inspect the error details for more information., NSUnderlyingError=0x283f43c30 {Error Domain=FIRAuthInternalErrorDomain Code=3 "(null)" UserInfo={NSUnderlyingError=0x283f9bae0 {Error Domain=com.google.HTTPStatus Code=503 "(null)" UserInfo={data={length = 207, bytes = 0x7b0a2020 22657272 6f72223a 207b0a20 ... 5d0a2020 7d0a7d0a }, data_content_type=application/json; charset=UTF-8}}, FIRAuthErrorUserInfoDeserializedResponseKey={
code = 503;
errors = (
{
domain = global;
message = "Error code: 33";
reason = backendError;
}
);
message = "Error code: 33";
}}}}
I've tried adding the firebase auth SDK: https://github.com/firebase/firebase-ios-sdk to the project and I get an error in a random file that says "redfinition of module 'Firebase'" and other stack overflow posts say to just delete the SDK and it'll solve your issue.
I'm really confused, why does it only work in the simulator and not my device?
Is the SDK really the solution and I need to find another way around the redefinition issue?
Thanks for your help in advance!

Getting the error code and description from a session.dataTask call

I am calling some APIs from my app. I'd like to get and process the error code. There seems to be a lot of information on how to retrieve and process the response codes, but very little on the error code. I'd like to access the error code in case, say the user has no internet connection so the call to the API fails. I am using this code:
session.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) in
if let error = error {
print("Tide Station API call failed with error \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Tide Station API call response is \(response.statusCode)")
}
if let data = data
{
do {
let result = try JSONDecoder().decode(TideStations.self, from: data)
self.tideStations = result.stations
print("\(result.stations.count) Tide Stations successfully loaded")
self.showTideStationsOnMap()
} catch {
print("Error while stations parsing: \(error)")
}
}
}).resume()
Which generates the following output in the debug area when my device is is airplane mode, i.e. I am forcing one sure way of the API call failing: (note I have bolded the area from my error handling print statement)
2020-02-26 17:57:58.235368+0000 APITest[5464:2590011] Task <006E7876-214F-41E3-8BDE-26960AF1F554>.<1> finished with error [-1009] Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSUnderlyingError=0x283a918f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https://api.sunrise-sunset.org/json?lat=57.5081&lng=-1.7841&date=2020-06-21&formatted=0, NSErrorFailingURLKey=https://api.sunrise-sunset.org/json?lat=57.5081&lng=-1.7841&date=2020-06-21&formatted=0, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.}
Astronomical Times API call failed with error Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSUnderlyingError=0x283a918f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, NSErrorFailingURLStringKey=https://api.sunrise-sunset.org/json?lat=57.5081&lng=-1.7841&date=2020-06-21&formatted=0, NSErrorFailingURLKey=https://api.sunrise-sunset.org/json?lat=57.5081&lng=-1.7841&date=2020-06-21&formatted=0, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.}
In this example, I want to extract from this the fact that the internet connection appears down and advise the user. I would have thought that there would be similar support for error code extraction as there is for result code extraction. Would it be more normal to just say an error occurred (easy to detect) and handle elsewhere (e.g. detect no internet before calling the API)? If so, what shout I be guarding for?
The Error class in swift does not contain the error code and the error domain in it. However, if you print the error you can definitely see the error code and domain in the logs.
You can access those by simply casting the Swift's Error to the old Objective-C NSError. This classes are toll-free bridgeable, so there is no need to check if the cast fails or forcefully perform the cast with as!. Simply do:
let nsError = error as NSError
print("Error code is: \(nsError.code)")

CNContactStore execute fails

I am working out how to use the Contacts framework, however some fairly simple code to create a contact is failing with an unexpected result. This is my code:
let Store = CNContactStore()
Store.requestAccess(for: .contacts, completionHandler:{ success, error in
if success {
let Contact = CNMutableContact()
Contact.givenName = "Dave"
Contact.familyName = "Nottage"
let SaveRequest = CNSaveRequest()
SaveRequest.add(Contact, toContainerWithIdentifier: nil)
do {
try Store.execute(SaveRequest)
print("Success")
}
catch let error as NSError {
print(error.localizedDescription)
}
} else {
print("No access")
}
})
..and this is the result:
2019-02-22 10:30:56.050344+1030 ContactsTest[30329:25254955] [default] Unable to load Info.plist exceptions (eGPUOverrides)
2019-02-22 10:30:57.973724+1030 ContactsTest[30329:25254955] Could not get real path for Address Book lock folder: open() for F_GETPATH failed.
2019-02-22 10:30:57.973954+1030 ContactsTest[30329:25254955] Unable to open file lock: <ABProcessSharedLock: 0x600001752ac0: name=(null), lockFilePath=(null), localLock=<NSRecursiveLock: 0x600002914a80>{recursion count = 0, name = nil}, fileDescriptor=-1> Error Domain=NSPOSIXErrorDomain Code=14 "Bad address" UserInfo={ABFileDescriptor=-1}
The operation couldn’t be completed. (Foundation._GenericObjCError error 0.)
Any ideas on what might be causing this?
Edit: Note also that this is being compiled for macOS 10.14 SDK, and is running on macOS 10.14.3
The answer is to check the Contacts checkbox of App Data in the App Sandbox section in Capabilities and turn on the switch for App Sandbox.
Make sure you added key NSContactsUsageDescription in Info.plist.
Please refer to link.
Important
An iOS app linked on or after iOS 10.0 must include in its Info.plist
file the usage description keys for the types of data it needs to
access or it will crash. To access Contacts data specifically, it must
include NSContactsUsageDescription.

Swift: Proper Firebase error-handling

I'm not able to understand why neither print lines are executed when running the following code:
ref.child("schools/\(schoolTextField.text!)/settings/pin").observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot.value)
}, withCancel: { (error) in
print(error.localizedDescription)
})
It used to work, until I made some changes regarding firebase authentication, but I don't see why the withCancel block is not executed!
How do I catch whatever error is occuring here? No error-message is printed in the log.
EDIT:
I found a similar question here which suggests that the problem might be related to the authentication after all. In appDelegate's didFinishLaunchingWithOptions I check if the user auth-token exists in Firebase Auth:
Auth.auth().currentUser?.getIDTokenForcingRefresh(true, completion: { (response, error) in
guard error == nil, let uid = response else {
print(error)
return
}
...
})
In current case there is an error, which is printed:
Error Domain=FIRAuthErrorDomain Code=17011 "There is no user record corresponding to this identifier. The user may have been deleted."
I'm now also getting these errors printed in the log:
[Common] _BSMachError: port b43b; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
[Common] _BSMachError: port b43b; (os/kern) invalid name (0xf) "Unable to deallocate send right"
Try this way:
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshots {
print("SNAP: \(snap)")
}
Also The error code 17011 is a user not found error see FIRAuthErrorCode for more info also it's better you create a Dataservice class to handle your interaction with firebase see Creating A Reusable Firebase Data Service for more info.

Implementing Github authentication with Firebase and Xcode (swift)

I've been receiving this error "An internal error has occurred, print and inspect the error details for more information" when trying to login through the access-token I receive from Github.
let credential = FIRGitHubAuthProvider.credentialWithToken(accessToken)
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
if let error = error {
print(error.localizedDescription)
}
}
It seems the issue is happening here but I'm not so sure why. Thank you in advance!