Its bit early to ask but I'm planning to add feature specially for FaceID, so before that I need to validate either device support FaceID or not?
Need suggestion and help.
Thanks in advance.
Objective-C version
- (BOOL) isFaceIdSupported{
if (#available(iOS 11.0, *)) {
LAContext *context = [[LAContext alloc] init];
if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]){
return ( context.biometryType == LABiometryTypeFaceID);
}
}
return NO;
}
I found that you have to call canEvaluatePolicy before you will properly get the biometry type. If you don't you'll always get 0 for the raw value.
So something like this in Swift 3, tested and working in Xcode 9.0 & beta 9.0.1.
class func canAuthenticateByFaceID () -> Bool {
//if iOS 11 doesn't exist then FaceID doesn't either
if #available(iOS 11.0, *) {
let context = LAContext.init()
var error: NSError?
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
//As of 11.2 typeFaceID is now just faceID
if (context.biometryType == LABiometryType.typeFaceID) {
return true
}
}
}
return false
}
You could of course write that just to see if it's either biometric and return the type along with the bool but this should be more than enough for most to work off of.
Thanks Ashley Mills, I created a function to detect FaceID in Device.
- (BOOL)canAuthenticateByFaceID {
LAContext *context = [[LAContext alloc] init];
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
if (context.biometryType == LABiometryTypeFaceID && #available(iOS 11.0, *)) {
return YES;
} else {
return NO;
}
}
}
Hope this will help other. Happy coding!!
Finally I wrote my own Library for detecting FaceID here you find
Swift 4 compatible version
var isFaceIDSupported: Bool {
if #available(iOS 11.0, *) {
let localAuthenticationContext = LAContext()
if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
return localAuthenticationContext.biometryType == .faceID
}
}
return false
}
+(BOOL)supportFaceID
{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
// call this method only to get the biometryType and we don't care about the result!
[myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError];
NSLog(#"%#",authError.localizedDescription);
if (#available(iOS 11.0, *)) {
return myContext.biometryType == LABiometryTypeFaceID;
} else {
// Device is running on older iOS version and OFC doesn't have FaceID
return NO;
}
}
Related
I have an example in Swift language:
guard let windowScene = view.window?.windowScene else { return }
windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .portrait)) { error in }
I can't write it in Objective C:
UIWindowScene *windowScene = self.view.window.windowScene;
[windowScene requestGeometryUpdateWithPreferences: UIInterfaceOrientationMaskPortrait errorHandler:nil];
Please tell me how to write correctly I will be grateful for any help.
One way to write that Swift code in Objective-C would be:
UIWindowScene *windowScene = self.view.window.windowScene;
if (!windowScene) { return; }
UIWindowSceneGeometryPreferences *preferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortrait];
[windowScene requestGeometryUpdateWithPreferences:preferences errorHandler:^(NSError * _Nonnull error) {
// Handle error here
}];
I am using react-native 0.62.2 version and datetimepicker version 3.0.1. As I am trying to build the project with xcode, the following errors are being shown:
Use of undeclared identifier 'UIDatePickerStyleCompact'
Use of undeclared identifier 'UIDatePickerStyleWheels'
Property 'preferredDatePickerStyle' not found on object of type
'RNDateTimePicker *'
Property 'preferredDatePickerStyle' not found on object of type
'UIDatePicker*'
Implicit conversion of 'NSInteger' (aka 'long') to 'id' is
disallowed with ARC
Statement requires expression of integer type ('__strong id'
invalid)
Implicit conversion of 'UIDatePickerMode' (aka 'enum
UIDatePickerMode') to 'id' is disallowed with ARC
Use of undeclared identifier 'UIDatePickerStyleWheels'
The following is the code inside RNDateTimePickerManager.h
#import "RNDateTimePickerManager.h"
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import "RNDateTimePicker.h"
#import <React/UIView+React.h>
#implementation RCTConvert(UIDatePicker)
RCT_ENUM_CONVERTER(UIDatePickerMode, (#{
#"time": #(UIDatePickerModeTime),
#"date": #(UIDatePickerModeDate),
#"datetime": #(UIDatePickerModeDateAndTime),
}), UIDatePickerModeTime, integerValue)
RCT_ENUM_CONVERTER(UIDatePickerStyle, (#{ //Error 5
#"default": #(UIActionSheetStyleAutomatic),
#"compact": #(UIDatePickerStyleCompact), //Error 1
#"spinner": #(UIDatePickerStyleWheels), //Error 2
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
#"inline": #(UIDatePickerStyleInline),
#endif
}), UIActionSheetStyleAutomatic, integerValue)
#end
#implementation RNDateTimePickerManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
return [RNDateTimePicker new];
}
+ (NSString*) datepickerStyleToString: (UIDatePickerStyle) style {
// RCTConvert does not handle this.?
switch (style) { //Error 6
case UIDatePickerStyleCompact:
return #"compact";
case UIDatePickerStyleWheels:
return #"spinner";
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
case UIDatePickerStyleInline:
return #"inline";
#endif
default:
[NSException raise:#"Unsupported style value" format:#"UIDatePickerStyle of %ld is unsupported", (long)style];
return #"";
}
}
RCT_EXPORT_METHOD(getDefaultDisplayValue:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIDatePicker* view = [RNDateTimePicker new];
view.preferredDatePickerStyle = UIActionSheetStyleAutomatic; //Error 4
UIDatePickerMode renderedMode = [RCTConvert UIDatePickerMode:options[#"mode"]];
view.datePickerMode = renderedMode;
// NOTE afaict we do not need to measure the actual dimensions here, but if we do, just look at the original PR
UIDatePickerMode determinedDisplayValue = view.datePickerMode; //Error 7
resolve(#{
#"determinedDisplayValue": [RNDateTimePickerManager datepickerStyleToString:determinedDisplayValue],
});
});
}
RCT_EXPORT_VIEW_PROPERTY(date, NSDate)
RCT_EXPORT_VIEW_PROPERTY(locale, NSLocale)
RCT_EXPORT_VIEW_PROPERTY(minimumDate, NSDate)
RCT_EXPORT_VIEW_PROPERTY(maximumDate, NSDate)
RCT_EXPORT_VIEW_PROPERTY(minuteInterval, NSInteger)
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
RCT_REMAP_VIEW_PROPERTY(mode, datePickerMode, UIDatePickerMode)
RCT_REMAP_VIEW_PROPERTY(timeZoneOffsetInMinutes, timeZone, NSTimeZone)
RCT_CUSTOM_VIEW_PROPERTY(textColor, UIColor, RNDateTimePicker)
{
if (#available(iOS 14.0, *) && view.datePickerMode != UIDatePickerStyleWheels) { //Error 8
// prevents #247
return;
}
if (json) {
[view setValue:[RCTConvert UIColor:json] forKey:#"textColor"];
[view setValue:#(NO) forKey:#"highlightsToday"];
} else {
UIColor* defaultColor;
if (#available(iOS 13.0, *)) {
defaultColor = [UIColor labelColor];
} else {
defaultColor = [UIColor blackColor];
}
[view setValue:defaultColor forKey:#"textColor"];
[view setValue:#(YES) forKey:#"highlightsToday"];
}
}
// TODO vonovak setting preferredDatePickerStyle invalidates minuteinterval
RCT_CUSTOM_VIEW_PROPERTY(displayIOS, UIDatePickerStyle, RNDateTimePicker)
{
if (#available(iOS 13.4, *)) {
if (json) {
UIDatePickerMode propValue = [RCTConvert UIDatePickerStyle:json];
view.preferredDatePickerStyle = propValue; //Error 3
} else {
view.preferredDatePickerStyle = UIActionSheetStyleAutomatic;
}
}
}
#end
Is there any bug in the react-native datetimepicker?
For those who are still stuck on this, specifically using this library.
Starting from version 3.0.3, it require that your Xcode is at least v11 but they never mention that v11.3 will not work which a lot of people already noticed that you will need at least v11.6.
Mind you, downgrading might not really help you either as you're missing the point of update which addresses a lot of bugs e.g #217 fix
you can use latest stable XCode (11.6).
The best answer for this is to update xcode to at least v11.6. I have been on solving issues around this for more than 48 hours and at end when the app finish building successfully, i battled missing dependencies.
I am trying to re-write an app in swift which is currently in Objective-C. How would I change this single line into Swift, as my current attempt does not prove correct
Tabata *tabata = [notification object];
Here is the entire function:
- (void)stateChanged:(NSNotification*)notification
{
if (enabled)
{
Tabata *tabata = [notification object];
switch (tabata.getState) {
case EXERCISE:
case RELAXATION:
[player play];
break;
default:
break;
}
}
}
And here is what I've converted into Swift:
func stateChanged(notifcation: NSNotification) {
if enabled {
var tabata: Tabata! = notification.object //error "Use of unresolved identifier 'notification'"
switch tabata.getState() {
case .EXERCISE: fallthrough
case .RELAXATION:
player.play()
break
default:
break
}
}
}
In Swift you have to downcast objects of type AnyObject rather then declare the type
var tabata = notification.object as! Tabata
func stateChanged(notification: NSNotification) {
if(enabled) {
var tabata: Tabata = notification.object as! Tabata
switch tabata.getState() {
case .EXERCISE:
fallthrough
case .RELAXATION:
player.play()
break
default:
break
}
}
}
Hope this helps!
I've looked all over the internet for how to create local notifications with IOS 8. I found many articles, but none explained how to determine if the user has set "alerts" on or off. Could someone please help me!!! I would prefer to use Objective C over Swift.
You can check it by using UIApplication 's currentUserNotificationSettings
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]){ // Check it's iOS 8 and above
UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
if (grantedSettings.types == UIUserNotificationTypeNone) {
NSLog(#"No permiossion granted");
}
else if (grantedSettings.types & UIUserNotificationTypeSound & UIUserNotificationTypeAlert ){
NSLog(#"Sound and alert permissions ");
}
else if (grantedSettings.types & UIUserNotificationTypeAlert){
NSLog(#"Alert Permission Granted");
}
}
Hope this helps , Let me know if you need more info
To expand on Albert's answer, you are not required to use rawValue in Swift. Because UIUserNotificationType conforms to OptionSetType it is possible to do the following:
if let settings = UIApplication.shared.currentUserNotificationSettings {
if settings.types.contains([.alert, .sound]) {
//Have alert and sound permissions
} else if settings.types.contains(.alert) {
//Have alert permission
}
}
You use the bracket [] syntax to combine option types (similar to the bitwise-or | operator for combining option flags in other languages).
Swift with guard:
guard let settings = UIApplication.sharedApplication().currentUserNotificationSettings() where settings.types != .None else {
return
}
Here is a simple function in Swift 3 that checks whether at least one type of notification is enabled.
Enjoy!
static func areNotificationsEnabled() -> Bool {
guard let settings = UIApplication.shared.currentUserNotificationSettings else {
return false
}
return settings.types.intersection([.alert, .badge, .sound]).isEmpty != true
}
Thanks Michał Kałużny for the inspiration.
Edit: Take a look at #simeon's answer.
In Swift, you need to use rawValue:
let grantedSettings = UIApplication.sharedApplication().currentUserNotificationSettings()
if grantedSettings.types.rawValue & UIUserNotificationType.Alert.rawValue != 0 {
// Alert permission granted
}
Using the #simeon answer Xcode tells me that
'currentUserNotificationSettings' was deprecated in iOS 10.0: Use UserNotifications Framework's -[UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:] and -[UNUserNotificationCenter getNotificationCategoriesWithCompletionHandler:]
so here is the solution using the UNUserNotificationCenter for Swift 4:
UNUserNotificationCenter.current().getNotificationSettings(){ (settings) in
switch settings.alertSetting{
case .enabled:
//Permissions are granted
case .disabled:
//Permissions are not granted
case .notSupported:
//The application does not support this notification type
}
}
I think this code is more precise :
if ([[UIApplication sharedApplication] respondsToSelector:#selector(currentUserNotificationSettings)]) {
UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
if (types & UIUserNotificationTypeBadge) {
NSLog(#"Badge permission");
}
if (types & UIUserNotificationTypeSound){
NSLog(#"Sound permission");
}
if (types & UIUserNotificationTypeAlert){
NSLog(#"Alert permission");
}
}
Objective C + iOS 10
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus) {
case UNAuthorizationStatusNotDetermined:
break;
case UNAuthorizationStatusDenied:
break;
case UNAuthorizationStatusAuthorized:
break;
default:
break;
}
}];
I'm attempting to use Tony Million's Reachability within a new Swift based app. I have it implemented in another app I wrote in Obj C, but I'm having issues with getting the proper syntax in Swift. The code blocks are as follows:
override func viewDidLoad() {
super.viewDidLoad()
messageText.text = ""
var reach: Reachability = Reachability(hostName: "www.apple.com")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged", name: kReachabilityChangedNotification, object: nil)
reach.reachableBlock = Reachability()
{
dispatch_async(dispatch_get_main_queue(), {
self.messageText.text = "Enter search criteria...";
})
}
reach.unreachableBlock = Reachability()
{
dispatch_async(dispatch_get_main_queue(), {
self.messageText.text = "Attempting to contact network...";
})
}
reach.startNotifier()
}
AND
func reachabilityChanged(note: NSNotification)
{
var reach: Reachability = Reachability()
if(reach.isReachable())
{
messageText.text = "Enter search criteria...";
}
else
{
messageText.text = "Attempting to contact network...";
}
}
My issues are first, my "blocks" for "reachable" and "unreachable" are not the correct syntax and I'm at a loss for what is the proper syntax for these blocks. My second issue is with the "reachabilityChanged" function. I get an error stating "-[_TtC9icdDRPlus20SearchViewController reachabilityChanged]: unrecognized selector sent to instance" which I'm again at a loss. Condsider my Obj C code as follows:
-(void)viewDidLoad
{
[super viewDidLoad];
NSString *popUpShownOnce = #"YES";
NSInteger swipeCount = 0;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:popUpShownOnce forKey:#"popDisplayed"];
[defaults setInteger:swipeCount forKey:#"showswipearrows"];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
Reachability * reach = [Reachability reachabilityWithHostname:#"somesite.com"];
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
searchForText.placeholder = #"Enter search criteria...";
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
searchForText.placeholder = #"Attempting to contact network...";
});
};
[reach startNotifier];
}
-(void)reachabilityChanged:(NSNotification*)note
{
Reachability * reach = [note object];
if([reach isReachable])
{
searchForText.placeholder = #"Enter search criteria...";
}
else
{
searchForText.placeholder = #"Attempting to contact network...";
}
}
Assistance is greatly appreciated. The questions are as follows:
1. What is the proper translation for the reachable and unreachable blocks from Obj C to Swift?
2. If my addObserver call is correct, why might I get the unrecognized selector error? If not correct, what is the proper call?
Thanks in advance.
The correct syntax for closures is { (<params>) -> <return type> in <statements> }:
reach.reachableBlock = { (reachability) in
dispatch_async(dispatch_get_main_queue(), {
self.messageText.text = "Enter search criteria...";
})
}
With NSNotificationCenter, looks like you missed the colon in the selector argument:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: kReachabilityChangedNotification, object: nil)
Your error after making the changes that #Austin recommended is that self.reachabilityRef in SCNetworkReachabilitySetCallback is NULL.
try:
func reachabilityChanged(note: NSNotification!) {
var reach: Reachability! = Reachability(reachabilityRef: note.object as SCNetworkReachability)
if(reach.isReachable()) {
messageText.text = "Enter search criteria...";
} else {
messageText.text = "Attempting to contact network...";
}
}
UPDATE:
It would seem that SCNetworkReachability is not currently fully working with Swift: according to this: https://twitter.com/marksands/status/474717606004273152
I got it to work like this:
var reachability: Reachability?
override func viewDidLoad() {
super.viewDidLoad()
// Setup reachability
reachability = Reachability(hostName: "www.google.com")
reachability!.reachableBlock = { (reach) in
dispatch_async(dispatch_get_main_queue(), {
self.titleLabel.attributedText = Utilities.myAttributedText("Online", mySize: 18, myFont: "HelveticaNeue", myColor: UIColor.whiteColor())
self.titleLabel.sizeToFit()
})
}
reachability!.unreachableBlock = { (reach) in
dispatch_async(dispatch_get_main_queue(), {
self.titleLabel.attributedText = Utilities.myAttributedText("Offline", mySize: 18, myFont: "HelveticaNeue", myColor: UIColor.whiteColor())
self.titleLabel.sizeToFit()
})
}
reachability!.startNotifier()
}
this worked for me:
//Reachability
myReachabilityInstance = Reachability(hostName: "www.google.com")
myReachabilityInstance?.reachableOnWWAN = false
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityDidChangeMethod", name: kReachabilityChangedNotification, object: nil)
myReachabilityInstance?.startNotifier()