What are the delegate methods for ReplayKit's initial alert choices? - ios

When the the user first decides to use ReplayKit there is an alert that appears. It gives 3 choices:
-Record Screen and Microphone
-Record Screen Only
-Don’t Allow
What are the delegate methods so that I can find out which option a user choose?

There aren't any delegate methods to determine which option a user chooses. You have to use the completionHandler and .isMicrophoneEnabled to determine the chosen option.
Once an option is chosen the completionHandler is called:
If the user chooses Don't Allow then the error code will run
If the user chooses Record Screen & Microphone then .isMicrophoneEnabled will get set to true
If the user chooses Record Screen Only then .isMicrophoneEnabled will get set to false
Inside the completionHandler you can check to see their choice then do whatever you need to do from that point on. Read the 2 comments in the completionHandler part of the code below.
let recorder = RPScreenRecorder.shared()
recorder.startCapture(handler: { [weak self](buffer, bufferType, err) in
// ...
}, completionHandler: { (error) in
// 1. If the user chooses "Dont'Allow", the error message will print "The user declined application recording". Outside of that if an actual error occurs something else will print
if let error = error {
print(error.localizedDescription)
print("The user choose Don't Allow")
return
}
// 2. Check the other 2 options
if self.recorder.isMicrophoneEnabled {
print("The user choose Record Screen & Microphone")
} else {
print("The user choose Record Screen Only")
}
})
The safe way to do this so that you know how to respond to each error code is to use a switch statement on the error codes:
}, completionHandler: { (error) in
if let error = error as NSError? {
let rpRecordingErrorCode = RPRecordingErrorCode(rawValue: error.code)
self.errorCodeResponse(rpRecordingErrorCode)
}
})
func errorCodeResponse(_ error: RPRecordingErrorCode?) {
guard let error = error else { return }
switch error {
case .unknown:
print("Error cause unknown")
case .userDeclined:
print("User declined recording request.")
case .disabled:
print("Recording disabled via parental controls.")
case .failedToStart:
print("Recording failed to start.")
case .failed:
print("Recording error occurred.")
case .insufficientStorage:
print("Not enough storage available on the device.")
case .interrupted:
print("Recording interrupted by another app.")
case .contentResize:
print("Recording interrupted by multitasking and content resizing.")
case .broadcastInvalidSession:
print("Attempted to start a broadcast without a prior session.")
case .systemDormancy:
print("Recording forced to end by the user pressing the power button.")
case .entitlements:
print("Recording failed due to missing entitlements.")
case .activePhoneCall:
print("Recording unable to record due to active phone call.")
default: break
}
}

If you only want to detect when Don't Allow is tapped, here is a simple solution:
recorder.startCapture(handler: { [self] (sampleBuffer, sampleType, passedError) in
if let passedError = passedError {
print(passedError.localizedDescription)
return
}
}) { err in
if let error = err {
if error._code == RPRecordingErrorCode.userDeclined.rawValue {
print("User didn't allow recording")
}
}
}

Related

Active my app when user walked 1 km and then 5km and so on. by using healthkit in ios swift when app is not running or in background

I have followed the answers of this question -
Healthkit background delivery when app is not running
on stackoverflow but not achieved my goal.
I want to notify user using local notification when he/she walked 1 km exact, when app is in background and not running state.
I am still not able to read the distance from Healthkit in background as well.
But when app is in foreground then only my code works and the code is as blow
let healthKitStore = HKHealthStore()
let distanceType = HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!
let query:HKObserverQuery = HKObserverQuery(sampleType: distanceType, predicate: nil) { (query, HKObserverQueryCompletionHandler, error) in
//here I schedule my local notification
// I want to read the distance here and also want to notify user.
self.callLocalNotification(1)
HKObserverQueryCompletionHandler()
}
healthKitStore?.execute(query)
healthKitStore?.enableBackgroundDelivery(for: distanceType, frequency: .immediate, withCompletion: { (succeeded, error) in
if succeeded{
print("Enabled background delivery of Distance changes")
} else {
if let theError = error{
print("Failed to enable background delivery of Distance changes.")
print("Error = \(theError)")
}
}
})
func callLocalNotification(_ distance:Int)
{
// Request Notification Settings
UNUserNotificationCenter.current().getNotificationSettings { (notificationSettings) in
switch notificationSettings.authorizationStatus {
case .notDetermined:
self.requestAuthorization(completionHandler: { (success) in
guard success else { return }
// Schedule Local Notification
self.scheduleLocalNotification(distance)
})
case .authorized:
// Schedule Local Notification
self.scheduleLocalNotification(distance)
case .denied:
print("Application Not Allowed to Display Notifications")
}
}

iOS Customize Local Authentication with Touch ID

I am using the following code to implement the touchID/passcode authentication in my app
let context : LAContext = LAContext()
var error: NSError?
// Check if the device can evaluate the policy.
if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthentication, error: &error) {
context.evaluatePolicy(LAPolicy.deviceOwnerAuthentication,
localizedReason: messageString,
reply: { (success: Bool, evalPolicyError: Error?) -> Void in
if success {
// ...
}
else {
switch evalPolicyError!._code {
case LAError.systemCancel.rawValue:
print("Authentication was cancelled by the system")
case LAError.userCancel.rawValue:
print("Authentication was cancelled by the user")
case LAError.userFallback.rawValue:
print("User selected to enter custom password")
OperationQueue.main.addOperation({ () -> Void in
// ...
})
default:
print("Authentication failed")
OperationQueue.main.addOperation({ () -> Void in
// ...
})
}
}
})
}
Is is possible to customize it? For example:
Choose the number of TouchID attempts before switching to passcode?
In the first AlertView let user choose to switch to passcode with a button (in the current implementation you can access the passcode only if you fail the TouchID auth)

Detect when user tapped Don't Allow when making changes to photo library

When you want to make a change to a PHAsset, you wrap it up in a performChanges block. You get a success Bool and an error NSError in the completion block. Now I would like to show an alert to the user in the case the request failed. This does the trick:
PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
let request = PHAssetChangeRequest(forAsset: asset)
request.creationDate = date
}, completionHandler: { (success: Bool, error: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue()) {
if let error = error {
//present alert
}
}
})
The problem is when the user taps Don't Allow it also presents the alert. I don't want to do that, the user intentionally canceled it so there's no need to inform them it failed. But how can I detect that's what has occurred? The error userInfo is nil, it doesn't seem it provides any useful info to detect that case. Am I missing something?
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
NSLog(#"%ld",(long)status);
switch (status) {
case PHAuthorizationStatusAuthorized:
// code for display photos
NSLog(#"ffefwfwfwef");
case PHAuthorizationStatusRestricted:
break;
case PHAuthorizationStatusDenied:
//code for Dont Allow code
break;
default:
break;
}
}];
This is now possible by checking if the error is a PHPhotosError and if so checking its code to see if it's .userCancelled.
PHPhotoLibrary.shared().performChanges({
let request = PHAssetChangeRequest(forAsset: asset)
request.creationDate = date
}) { success, error in
guard let error = error else { return }
guard (error as? PHPhotosError)?.code != .userCancelled else { return }
DispatchQueue.main.async {
//present alert
}
}

How to get fingerprint dat in ios 8?

For this i use La Authentication framework but with the help of that i don't got fingerprint data and it just returns me boolean value i.e true and false , so it cant help i want fingerprint data in variable so further i will process it.
Help me.
following is the sample code,
func authenticateUser() {
...
// Check if the device can evaluate the policy.
if context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error) {
[context .evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in
if success {
}
else {
// If authentication failed then show a message to the console with a short description.
// In case that the error is a user fallback, then show the password alert view.
println(evalPolicyError?.localizedDescription)
switch evalPolicyError!.code {
case LAError.SystemCancel.toRaw():
println("Authentication was cancelled by the system")
case LAError.UserCancel.toRaw():
println("Authentication was cancelled by the user")
case LAError.UserFallback.toRaw():
println("User selected to enter custom password")
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
default:
println("Authentication failed")
NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
self.showPasswordAlert()
})
}
}
})]
}
}
You can't, Apple does not allow access to the fingerprint data. This has to do with security.
The iOS SDK only allows you let a user validate them selfs with the Touch ID.

Get notified when the user makes selection for allowing access to Camera in iOS

When the app tries to access the Camera API's in iOS than an OS level alertview is shown.
The user here has to allow access to camera or disable the access.
My question is how can I get notified of the selection made by the user..?
Say he selected don't allow access than is there any notification raised which I can use in my app..?
Any help is appreciated.
Instead of letting the OS show the alert view when the camera appears, you can check for the current authorization status, and request for the authorization manually. That way, you get a callback when the user accepts/rejects your request.
In swift:
let status = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
if status == AVAuthorizationStatus.Authorized {
// Show camera
} else if status == AVAuthorizationStatus.NotDetermined {
// Request permission
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted) -> Void in
if granted {
// Show camera
}
})
} else {
// User rejected permission. Ask user to switch it on in the Settings app manually
}
If the user has previously rejected the request, calling requestAccessForMediaType will not show the alert and will execute the completion block immediately. In this case, you can choose to show your custom alert and link the user to the settings page. More info on this here.
Taken from Kens answer, I've created this Swift 3 protocol to handle permission access:
import AVFoundation
protocol PermissionHandler {
func handleCameraPermissions(completion: #escaping ((_ error: Error?) -> Void))
}
extension PermissionHandler {
func handleCameraPermissions(completion: #escaping ((_ error: Error?) -> Void)) {
let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
switch status {
case .authorized:
completion(nil)
case .restricted:
completion(ClientError.noAccess)
case .notDetermined:
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
if granted {
completion(nil)
} else {
completion(ClientError.noAccess)
}
}
case .denied:
completion(ClientError.noAccess)
}
}
}
You can then conform to this protocol and call it in your class like so:
handleCameraPermissions() { error in
if let error = error {
//Denied, handle error here
return
}
//Allowed! As you were

Resources