What does joinOnce do in NEHotspotConfiguration do? - ios

I am trying to do autoconnect in iOS with below code
if([Utils isEmpty:password]){
configuration = [[NEHotspotConfiguration alloc] initWithSSID: wifiSSID];
}else{
configuration = [[NEHotspotConfiguration alloc] initWithSSID: wifiSSID passphrase: password isWEP: NO];
}
configuration.joinOnce = YES;
/* Alert the OS that the user wants to connect to the WiFi */
[[NEHotspotConfigurationManager sharedManager] applyConfiguration: configuration completionHandler: ^ (NSError * _Nullable error) {
if (nil == error) {
DLog (# "Is Connected!!");
[WiFiManager sendCallback:CONNECTED callback:callback];
} else {
DLog (# "Error is:%#", error);
[WiFiManager sendCallback:UNKNOWN callback:callback];
}}];
Here I have joinOnce = YES.
What does this actually do when it is set to NO.
I don't find any real difference between YES and NO.
Anyone please explain.

When joinOnce is set to true, it means that the connection to that hotspot will be disconnected and the configuration will be forgotten as soon as the device sleeps or your application has been in the background for some time.

Related

iPad Pro(3) M1 iOS 15.0, Code=201 "Siri and Dictation are disabled"

An Objective-C project of iOS. Used the Apple SpeechKit. The Speech recognition send a error 'Error Domain=kLSRErrorDomain Code=201 "Siri and Dictation are disabled" UserInfo={NSLocalizedDescription=Siri and Dictation are disabled}'
An error will be reported in resultHandler: Error Domain=kLSRErrorDomain Code=201 "Siri and Dictation are disabled" UserInfo={NSLocalizedDescription=Siri and Dictation are disabled}
- (void)resetRecognitionTask
{
// Cancel the previous task if it's running.
if (self.recognitionTask) {
//[self.recognitionTask cancel]; // Will cause the system error and memory problems.
[self.recognitionTask finish];
}
self.recognitionTask = nil;
// Configure the audio session for the app.
NSError *error = nil;
if (AVAudioSession.sharedInstance.categoryOptions != (AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth)) {
[AVAudioSession.sharedInstance setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeMeasurement options:AVAudioSessionCategoryOptionMixWithOthers|AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth error:&error];
}
//[AVAudioSession.sharedInstance setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDuckOthers error:&error];
if (error)
{
[self stopWithError:error];
return;
}
[AVAudioSession.sharedInstance setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
if (error)
{
[self stopWithError:error];
return;
}
// Create and configure the speech recognition request.
self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
self.recognitionRequest.taskHint = SFSpeechRecognitionTaskHintConfirmation;
// Keep speech recognition data on device
if (#available(iOS 13, *)) {
self.recognitionRequest.requiresOnDeviceRecognition = NO;
}
// Create a recognition task for the speech recognition session.
// Keep a reference to the task so that it can be canceled.
__weak typeof(self)weakSelf = self;
self.speechRecognizer = nil;
self.recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
__strong typeof(self)strongSelf = weakSelf;
if (result != nil) {
[strongSelf resultCallback:result];
}
}];
}
I think this is an oversight of iOS system.
Solution: Settings-> General -> Keyboards -> Enable Dictation
Turn it ON.

how to check No Fingerprints added for Touch ID in iOS

I am integrating Touch ID access in one of my app. I have successfully integrated it. Here is that code:
dispatch_queue_t highPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.75 * NSEC_PER_SEC), highPriorityQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
LAContext *context = [[LAContext alloc] init];
isTouchExists = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil];
if (isTouchExists) {
NSString * keychainItemIdentifier;
NSString * keychainItemServiceName;
keychainItemIdentifier = #"fingerprintKeychainEntry";
keychainItemServiceName = [[NSBundle mainBundle] bundleIdentifier];
NSData * pwData = [#"the password itself does not matter" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary * attributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
(__bridge id)(kSecClassGenericPassword), kSecClass,
keychainItemIdentifier, kSecAttrAccount,
keychainItemServiceName, kSecAttrService, nil];
CFErrorRef accessControlError = NULL;
SecAccessControlRef accessControlRef = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
kSecAccessControlUserPresence,
&accessControlError);
if (accessControlRef == NULL || accessControlError != NULL)
{
NSLog(#"Cannot create SecAccessControlRef to store a password with identifier “%#” in the key chain: %#.", keychainItemIdentifier, accessControlError);
}
attributes[(__bridge id)kSecAttrAccessControl] = (__bridge id)accessControlRef;
attributes[(__bridge id)kSecUseNoAuthenticationUI] = #YES;
attributes[(__bridge id)kSecValueData] = pwData;
CFTypeRef result;
OSStatus osStatus = SecItemAdd((__bridge CFDictionaryRef)attributes, &result);
if (osStatus != noErr)
{
NSError * error = [[NSError alloc] initWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
NSLog(#"Adding generic password with identifier “%#” to keychain failed with OSError %d: %#.", keychainItemIdentifier, (int)osStatus, error);
}
//other my code for success
}
});
});
Now, If I remove all the fingerprints from settings in iPhone, This code will work and ask for passcode. So My question is:
how can I come to know that there is no any fingerprints added for Touch ID?
I don't want to show iOS device passcode screen as I have already built passcode screen for my app security. So is there any option to check device have atleast one fingerprint available for Touch ID access?
Thanks in advance.
======== EDIT 1 ===========
It is working on my side also. The issue is I need to check it each time when I am asking for Touch ID. I need to fetch status in viewWillAppear or in applicationDidBecomeActive each time whenever I want to use Touch ID access in app, as I am removing fingers run time, it may not reflecting in my code so I need to fetch each time.
canEvaluatePolicy:error: will be Error : LAErrorTouchIDNotEnrolled
Authentication could not start because Touch ID has no enrolled
fingers.
APPLE DOC Ref.
Try:
LAContext *context = [[LAContext alloc] init];
NSError *error;
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:#"My Reason" reply:^(BOOL success, NSError * _Nullable error) {
}];
}else{
if (error.code == LAErrorTouchIDNotEnrolled) {
NSLog(#"Error: %#", error.localizedDescription);
}
}
If there are no fingerprints registered, canEvaluatePolicy should return false.
Source : https://developer.apple.com/documentation/localauthentication/lacontext/1514149-canevaluatepolicy?language=objc

Optimistic concurrency in Azre iOS client SDK

I have a query regarding concurrency in Azure mobile client SDK.
for windows I found Conflict link for handling concurrency but I could not found the same for iOS client SDK.
Can anyone please suggest or help how to handle concurrency in iOS client SDK.
Here is the old Mobile Services page for handling conflicts with the iOS SDK. The setup for offline sync with the iOS SDK hasn't changed since then.
1) Set up an MSSyncContextDelegate and pass it to the MSSyncContext constructor when you create it.
2) Implement tableOperation:(MSTableOperation *)operation onComplete:(MSSyncItemBlock)completion in your delegate. After executing the operation, check for an MSErrorPreconditionFailed error code and decide what to do from there based on your app's needs.
- (void)tableOperation:(MSTableOperation *)operation onComplete:(MSSyncItemBlock)completion
{
[operation executeWithCompletion:^(NSDictionary *item, NSError *error) {
NSDictionary *serverItem = [error.userInfo objectForKey:MSErrorServerItemKey];
if (error.code == MSErrorPreconditionFailed) {
QSUIAlertViewWithBlock *alert = [[QSUIAlertViewWithBlock alloc] initWithCallback:^(NSInteger buttonIndex) {
if (buttonIndex == 1) { // Client
NSMutableDictionary *adjustedItem = [operation.item mutableCopy];
[adjustedItem setValue:[serverItem objectForKey:MSSystemColumnVersion] forKey:MSSystemColumnVersion];
operation.item = adjustedItem;
[self doOperation:operation complete:completion];
return;
} else if (buttonIndex == 2) { // Server
NSDictionary *serverItem = [error.userInfo objectForKey:MSErrorServerItemKey];
completion(serverItem, nil);
} else { // Cancel
[operation cancelPush];
completion(nil, error);
}
}];
NSString *message = [NSString stringWithFormat:#"Client value: %#\nServer value: %#", operation.item[#"text"], serverItem[#"text"]];
[alert showAlertWithTitle:#"Server Conflict"
message:message
cancelButtonTitle:#"Cancel"
otherButtonTitles:[NSArray arrayWithObjects:#"Use Client", #"Use Server", nil]];
} else {
completion(item, error);
}
}];
}

Getting Permission Denied error on manager loadFromPreferencesWithCompletionHandler

In my app I am trying to configure VPN settings in App load delegate. I am calling following method in my app delegate
- (void)configureVPN {
NEVPNManager *manager = [NEVPNManager sharedManager];
[manager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable loadError) {
if (loadError) {
NSLog(#"vpn setup error: %#", loadError);
} else {
[manager setOnDemandEnabled: YES];
NSMutableArray *rules = [[NSMutableArray alloc] init];
NEOnDemandRuleConnect *connectRule = [NEOnDemandRuleConnect new];
[rules addObject:connectRule];
[manager setOnDemandRules:rules];
[manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable saveError) {
if (saveError) {
NSLog(#"vpn setup error: %#", saveError);
} else {
NSLog(#"vpn config set");
NSError *connError;
[manager.connection startVPNTunnelAndReturnError:&connError];
if (connError) {
NSLog(#"Unable to connect to VPN: %#", connError);
} else {
NSLog(#"VPN connection established");
}
}
}];
}
}];
}
but I am getting error on manager loadFromPreferencesWithCompletionHandler
Error:
Failed to load the configuration: Error Domain=NEVPNErrorDomain Code=5 "permission denied" UserInfo={NSLocalizedDescription=permission denied}
I thought it was because of missing capabilities but Personal VPN is enabled in capabilities.
Go to Xcode -> Project -> Targets -> Capabilities and
Enable VPN and Enable Network Extensions.
To fix the issue, go to Xcode > Project > capabilities and enable personal VPN.
In my case, I had added the Capabilities correctly, but an error is still reported
when I restart my iPhone , then run the project, every thing work fine

watchOS Send Message not getting called

Hi I'm having an issue with my code it looks like send message isn't getting called for some reason, thanks
if ([[WCSession defaultSession] isReachable]) {
NSLog(#"Initiating WCSession to Read iPhone Data");
[[WCSession defaultSession] sendMessage:watchData replyHandler:^(NSDictionary *dataFromPhone) {
NSLog(#"Sending Empty Write Data Array to iPhone...%#", watchData);
}
errorHandler:^(NSError *error) {
// Log error
NSLog(#"Error: %#", error);
}];
} else {
//we aren't in range of the phone, they didn't bring it on their run
NSLog(#"Unable to connect to iPhone");
}
From what I see this is the code that runs on iOS, which controls whether the Apple Watch is reachable, but you have to remember (if you have not done of course) to enable the session from either device with the following code, so enable the communication system
if (WCSession.isSupported()) {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}

Resources