How to get notification authorization status in swift 3? - swift

How can I check UNUserNotificationCenter for current authorization status in iOS 11? I've been looking for a while and found some code but it's not in swift 3 and some of functions were deprecated in iOS 10. Can anyone help?

Okay I found it:
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in
if(settings.authorizationStatus == .authorized)
{
print("Push authorized")
}
else
{
print("Push not authorized")
}
}
code by: Kuba

When getting the notification authorization status, there are actually three states it can be in, i.e.
authorized
denied
non-determined
A straightforward way to check these is with a switch-case where .authorized, .denied, and .nonDetermined are enums in UNAuthorizationStatus
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("Checking notification status")
switch settings.authorizationStatus {
case .authorized:
print("authorized")
case .denied:
print("denied")
case .notDetermined:
print("notDetermined")
}
}
Description of UNAuthorizationStatus can be found here in Apple's docs https://developer.apple.com/documentation/usernotifications/unauthorizationstatus

Related

StoreKit 2 unexpected behavior with consumable items

I'm trying to implement iAP with StoreKit 2. Maybe my code isn't very elegant but seems to work ;-)
But the following behavior I can#t understand:
If I first start my app in simulator or on my test device I can bought a consumable item. If I want to buy it again (how consumables should work) the app automatically restores the purchase and don't ask for purchase.
Is this a specific behavior in my test environment or do I understand consumables wrong?
Because StoreKit 2 is quite new I haven't found a tutorial in the internet that's fits for me.
Any hints are very wellcome :-)
Maybe I solved my problem. Can please someone approve it if I'm right?
I added await transaction.finish() to my purchase()
func purchaseTSBooster() {
self.boughtItem = true
Task.init {
guard let tsProduct = tsBoosterProducts.first else {return}
do {
let result = try await tsProduct.purchase()
switch result {
case .success(let verification):
switch verification {
case .verified(let transaction):
DispatchQueue.main.async {
self.tsBoosterID.append(transaction.productID)
}
await transaction.finish()
case .unverified(_, _):
break
}
case .userCancelled:
buyaborted = true
case .pending:
break
#unknown default:
break
}
}
catch {
print(error)
}
}
}

How to set a tuple in a AnyPublisher in SwiftUI

good morning community,
I have a very good question that I try to implement in a project but I am something new to combine
I want to do a function to check some permissions, but I want to return an AnyPublisher with a tuple inside, could someone help me who has already done it or know how to do it?
I put my code below.
func returnedPermisionReminderAuthorizationStatus(reminderPermission:EKAuthorizationStatus,calendarPermission:EKAuthorizationStatus) -> AnyPublisher<(EKAuthorizationStatus,EKAuthorizationStatus),Never>{
var reminderPermissionToPass:EKAuthorizationStatus = .notDetermined
var calendarPermissionToPass:EKAuthorizationStatus = .notDetermined
switch (reminderPermission){
case .notDetermined:
return Just(reminderPermissionToPass).eraseToAnyPublisher()
case .restricted:
reminderPermissionToPass = .restricted
return Just(reminderPermissionToPass).eraseToAnyPublisher()
case .denied:
reminderPermissionToPass = .denied
return Just(reminderPermissionToPass).eraseToAnyPublisher()
case .authorized:
reminderPermissionToPass = .authorized
return Just(reminderPermissionToPass).eraseToAnyPublisher()
#unknown default:
reminderPermissionToPass = .notDetermined
return Just(reminderPermissionToPass).eraseToAnyPublisher()
}
}
Is it possible to send a tuple in a just?
You can send a tuple from Just like this:
func returnedPermisionReminderAuthorizationStatus(
reminderPermission: EKAuthorizationStatus,
calendarPermission: EKAuthorizationStatus
) -> AnyPublisher<(EKAuthorizationStatus,EKAuthorizationStatus),Never>{
Just((reminderPermission,calendarPermission))
.eraseToAnyPublisher()
}
What about a PassthroughSubject ? If yes then try the following code :
let someResponse = PassthroughSubject<(Bool,String), Never>()
and then to receive
.onReceive(someResponse, perform: { (boolValue,StringValue) in
})

How to relinquish MacOS Camera,Microphone

In trying to code up a prototype, it struct me there's no way revert the request?
So, you add the entitlements of interest to your app's capabilities, and here is I check:
internal func avStatus(for media: AVMediaType) -> AVAuthorizationStatus {
let status = AVCaptureDevice.authorizationStatus(for: media)
switch status {
case .authorized: // The user has previously granted access to the microphone.
return .authorized
case .notDetermined: // The user has not yet been asked for microphone access.
return .notDetermined
case .denied: // The user has previously denied access.
return .denied
case .restricted: // The user can't grant access due to restrictions.
return .restricted
default:
Swift.print("Unknown AV status \(status) for .audio")
return status
}
}
I was thinking that a user action to request the use of the entitlement, and relinquish would be needed:
#objc #IBAction func audioVideoServicesPress(_ sender: AnyObject) {
let service = sender.title.components(separatedBy: " ").last
let media : AVMediaType = service == "Audio" ? .audio : .video
let status = self.avStatus(for: media)
guard ![.denied,.restricted].contains(status) else { return }
if status == .authorized {
print("how do we relinquish need in the a/v device")
}
else
{
AVCaptureDevice.requestAccess(for: media, completionHandler: { granted in
return
})
}
}
In other user actions, if they had disabled or denied, then I would route them to the proper settings app, but before I get there, how to undo the request?
This is no way to un-request access the a/v device?
I think that suggests I'm going about this all wrong?
There is nothing to "relinquish."
The user's button press is an intent. The user wants to perform some action that can be performed only if you have authorization. So if you have it or can get, your job now is to do it.
Okay, so either you have authorization or you don't. If authorization status is .undetermined, you might get it. If it's .authorized, you already did get it. In either of those cases, do what the user intends!
At the time of your print line, you have authorization so now go ahead and do whatever the user pressed the button intending to do.
Similarly, do not return in the completion handler for requesting access; instead, check granted and if true, do whatever the user pressed the button intending to do.
In any other case, you are hosed, so do nothing. The user's intent requires an authorization you don't have and cannot get. You might put up a dialog explaining why you can't do it, or send them off to where they can access their settings, but that's all you can do from here.

How to add state tracking AWS iOS?

I am having trouble using this code from AWS documentation to check the user state. No matter where I place it prints nothing. I also have properly set up my project with the AWS iOS SDK. I have placed in the AppDelegate and in different view controller's viewDidLoad and viewDidAppear however it still prints nothing.
AWSMobileClient.default().addUserStateListener(self) { (userState, info) in
switch (userState) {
case .guest:
print("user is in guest mode.")
case .signedOut:
print("user signed out")
case .signedIn:
print("user is signed in.")
case .signedOutUserPoolsTokenInvalid:
print("need to login again.")
case .signedOutFederatedTokensInvalid:
print("user logged in via federation, but currently needs new tokens")
default:
print("unsupported")
}
}

Accessing code in Swift 3 Error

New in Xcode 8 beta 4, NSError is bridged to the Swift Error protocol type. This affects StoreKit when dealing with failed SKPaymentTransactions. You ought to check to be sure the error didn't occur because the transaction was cancelled to know whether or not to show an error message to the user. You do this by examining the error's code. But with Error instead of NSError, there is no code defined. I haven't been able to figure out how to properly get the error code from Error.
This worked in the previous version of Swift 3:
func failedTransaction(_ transaction: SKPaymentTransaction) {
if let transactionError = transaction.error {
if transactionError.code != SKErrorCode.paymentCancelled.rawValue {
//show error to user
}
}
...
}
Now that error is an Error not NSError, code is not a member.
Another option to access code and domain properties in Swift 3 Error types is extending it as follow:
extension Error {
var code: Int { return (self as NSError).code }
var domain: String { return (self as NSError).domain }
}
Now in Xcode 8 and swift 3 the conditional cast is always succeeds, so you need do following:
let code = (error as NSError).code
and check the code for your needs. Hope this helps
Casting to SKError seems to be working for me in xCode 8 and Swift 3...
guard let error = transaction.error as? SKError else {return}
switch error.code { // https://developer.apple.com/reference/storekit/skerror.code
case .unknown: break
case .paymentCancelled: break
case .clientInvalid: break
case .paymentInvalid: break
case .paymentNotAllowed: break
case .cloudServiceNetworkConnectionFailed: break
case .cloudServicePermissionDenied: break
case .storeProductNotAvailable: break
}
No need for rawValue.
This is correct (Apple's own tests use this approach):
if error._code == SKError.code.paymentCancelled.rawValue { ... }
On the other hand, casting to NSError will probably be deprecated soon:
let code = (error as NSError).code // CODE SMELL!!
if code == SKError.code.paymentCancelled.rawValue { ... }
Use
error._code == NSURLErrorCancelled
to match the error code.
A lot is changing. Here's update for Xcode 11.
if let skError = transaction.error as? SKError, skError.code == .paymentCancelled {
print("Cancelled")
}