Within my swift app, this is the code I have to request for microphone and camera permissions.
class func requestCameraPermission(completionBlock:(Bool throws -> Void)) rethrows {
if (AVCaptureDevice.respondsToSelector(Selector("requestAccessForMediaType:completionHandler"))) {
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: {
granted in
dispatch_async(dispatch_get_main_queue()) {
try! completionBlock(granted)
}
})
} else {
try! completionBlock(true)
}
}
class func requestMicrophonePermission(completionBlock:(Bool throws -> Void)) rethrows {
if AVAudioSession.sharedInstance().respondsToSelector("requestRecordPermission:") {
AVAudioSession.sharedInstance().requestRecordPermission {
granted in
dispatch_async(dispatch_get_main_queue()) {
try! completionBlock(granted)
}
}
}
}
And this is the code I have to attach the camera and show an error if some permissions are missing.
func attachCamera() {
do {
try self.camera.start()
} catch BESwiftCameraErrorCode.CameraPermission {
self.showCameraPermissionAlert()
} catch BESwiftCameraErrorCode.MicrophonePermission {
self.showMicrophonePermissionAlert()
print("mic error!!")
} catch {
self.showUnknownErrorAlert()
}
}
I have tried not allowing for the camera permission. I see an alert box saying that I need camera permissions. The app does not crash.
But when I try not allowing the microphone permission, the app crashes.
With this line highlighted in the crash log:
try! completionBlock(granted)
And this error:
fatal error: 'try!' expression unexpectedly raised an error: TestApp.CameraErrorCode.MicrophonePermission: file /Library/Caches/com.apple.xbs/Sources/swiftlang_PONDEROSA/swiftlang_PONDEROSA-700.1.101.6/src/swift/stdlib/public/core/ErrorType.swift, line 50
What is causing this? How do I get the microphone permission alert to show instead of the app crashing?
Related
before ios16, my webrtc call work fine, but after upgrade to ios16, i can not hear anything, and can not talk to other. Here is my code:
func speakerOn() {
audioQueue.async { [weak self] in
guard let self = self else { return }
self.rtcAudioSession.lockForConfiguration()
do {
try self.rtcAudioSession.setCategory(AVAudioSession.Category.playAndRecord.rawValue, with: [.mixWithOthers])
try self.rtcAudioSession.setMode(AVAudioSession.Mode.voiceChat.rawValue)
try self.rtcAudioSession.overrideOutputAudioPort(.speaker)
try self.rtcAudioSession.setActive(true)
} catch let error {
debugPrint("Couldn't force audio to speaker: \(error)")
}
self.rtcAudioSession.unlockForConfiguration()
}
}
here is the problem i got:
"Couldn't force audio to speaker: Error Domain=NSOSStatusErrorDomain Code=1701737535 "Session activation failed" UserInfo={NSLocalizedDescription=Session activation failed}"
I can detect workout started on backgroun with apple watch, with below code
let workoutevent = HKObjectType.workoutType()
if store.authorizationStatus(for: workoutevent) != HKAuthorizationStatus.notDetermined {
store.enableBackgroundDelivery(for: workoutevent, frequency: .immediate, withCompletion: { (worked, error) in
print(worked)
print(error)
print("workoutevent enableBackgroundDelivery")
guard worked else {
self.logger.error("Unable to set up background delivery from HealthKit: \(error!.localizedDescription)")
print("workoutevent unable to set up background ")
fatalError()
}
if error != nil {
print("workoutevent error is ")
print(error)
}
})
backgroundObserver3 =
HKObserverQuery(sampleType: workoutevent,
predicate: nil,
updateHandler: processUpdate3(query:completionHandler3:error:))
if let queryworkout = backgroundObserver3 {
print("Starting workoutevent333 the background observer query.\(queryworkout)")
store.execute(queryworkout)
}
}else{
print("not determined....")
}
whenever I started workout on apple watch, it goes to
processUpdate3
very well,
but what I need to know is to when user finish workout.
how can I detect it ?
func processUpdate3(query: HKObserverQuery,
completionHandler3: #escaping () -> Void,
error: Error?) {
print("come here when work out started ")
...........
}
I don't see it in your code. But somewhere you must have an HKWorkoutSession. My app is set up to track running and I configure the session to begin like so;
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
do {
// HKWorkoutSession is set up here.
session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
workoutBuilder = session.associatedWorkoutBuilder()
} catch {
// handle errors
}
When the users taps the end workout button I call session.end()
Here is a link to the documentation.
I have implemented a sign up/ sign in feature using AWS Amplify and swift using my own View controllers instead of the Drop-in auth. The problem starts once I quit the app and restart it. After I do that the user is no longer signed in. I have set remember devices to always in the User Pool Settings. Has anyone ever encountered this problem?
Here is my function where the user gets confirmed and everything works properly except for remembering the user
#objc func confirm(){
print("confirm pressed")
guard let verificationCode = verificationTextField.text else{
return
}
AWSMobileClient.default().confirmSignUp(username: username, confirmationCode: verificationCode) { (signUpResult, error) in
if let signUpResult = signUpResult{
switch(signUpResult.signUpConfirmationState){
case .confirmed:
AWSMobileClient.default().deviceOperations.updateStatus(remembered: true) { (result, error) in //This is where I try to save the users device
print("User is signed up and confirmed")
DispatchQueue.main.async {
let signedInTabBar = SignedInTabBarController()
self.view.window!.rootViewController = signedInTabBar
}
}
case .unconfirmed:
print("User is not confirmed and needs verification via \(signUpResult.codeDeliveryDetails!.deliveryMedium) sent at \(signUpResult.codeDeliveryDetails!.destination!)")
case.unknown:
print("Unexpected case")
}
}else if let error = error {
print("\(error.localizedDescription)")
}
}
}
As I right understand you need to check if a user signed in or not. To do this you need to add this code on the start of the app or wherever you check a user status:
AWSMobileClient.default().initialize { userState, error in
OperationQueue.main.addOperation {
if let error = error {
AWSMobileClient.default().signOut()
assertionFailure("Logic after init error: \(error.localizedDescription)")
}
guard let userState = userState else {
AWSMobileClient.default().signOut()
return
}
guard userState == .signedIn else {
return
}
}
}
Its an Ionic app with some code written in native. Its uses cordova-plugin-firebase that for logging Crashlytics.
In the native part for iOS as well, we are trying to use Crashlytics to enable logging. However no matter what I try logs sent using CLSLogv aren't visible in dashboard.
Here is my code.
#objc(ImageUpload) class ImageUpload : CDVPlugin {
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
//https://docs.fabric.io/apple/crashlytics/enhanced-reports.html#custom-logging-in-swift
private func sendErrorToCrashlytics(error: String) {
NSLog("Error in send error function is \(error)")
CLSLogv("%#", getVaList([error]))
}
#objc(imageUpload:)
func imageUpload(command: CDVInvokedUrlCommand) {
registerBackgroundTask()
func execute() {
let db = SQLiteDatabase()
var recToUpLoad: PayloadModel? = nil
while(toCheck) {
do {
let record = try db.readValues() // THIS METHOD THROWS EXCEPTION
} catch Exceptions.SQLiteError(let error) {
self.sendErrorToCrashlytics(error: error) // IT COMES HERE AFTER EXCEPTION
}
}
}
DispatchQueue(label: "imageUploadPlugin",qos: .background).async
{
execute()
}
}
}
However CLSLogv is not visible at all in Crashlytics. However when I do Crashlytics.sharedInstance().throwException()
, I can see it in the dashboard.
Exceptions is enum
enum Exceptions: Error {
case SQLiteError(message: String)
case JSONError(message: String)
}
Hoping it may help someone. Somehow I couldn't get CLSLogv to work. I ended up creating an NSError object and log that in Crashlytics in catch block.
catch Exceptions.SQLiteError(let error) {
let userInfo = [NSLocalizedDescriptionKey: error.message, "query": error.query]
let errorObj = NSError(domain: "sqlite", code: 400, userInfo: userInfo)
Crashlytics.sharedInstance().recordError(errorObj)
}
I am trying to get TouchID to authenticate an action on my app. I need it to show an ImageView if successful.
Here is the code that I have in the ViewController
#IBOutlet weak var notificationImage: UIImageView!
#IBAction func touchBtn(_ sender: UIButton) {
context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) {
let reason = "Authenticate"
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason ) { success, error in
if success {
print("In closure")
// Move to the main thread because a state update triggers UI changes.
DispatchQueue.main.async{
print("In main thread: Success")
self.notificationImage.isHidden = false
}
} else {
DispatchQueue.main.async(execute: {
print("In main thread: Failed")
})
}
}
}
}
I am able to successfully authenticate using TouchID. It prints "In closure". But the block in the DispatchQueue.main.async does not execute and I am unable to update the notificationImage: UIImageView. Neither does it print anything in the sync{} blocks.
I have tried to disable Main Thread Checker and removing the DispatchQueue.main.async part, but the view sometimes refreshes and sometimes it doesn't. I want to use the recommended practice and update the UI from the main thread.
I am on Xcode 9 Swift 4 iOS 11.4
What could be wrong here.
try this code
#IBAction func touchBtn(_ sender: UIButton) {
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) {
let reason = "Authenticate"
context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason ) { success, error in
if success {
do {
print("In closure")
print("In main thread: Success")
self.notificationImage.isHidden = false
} catch let error as NSError {
print(error.localizedDescription)
print(error.description)
}
} else {
DispatchQueue.main.async(execute: {
print("In main thread: Failed")
})
}
}
}
}