I am testing usability of a website and am using WKWebView in a native app. The reason for this is so that I can use COSTouchVisualizer to show the touches, and RPScreenRecorder to record the interaction and the 'talk out loud' with the mic.
I have the following IBAction to start the recording:
@IBAction func startRecordSession(sender: AnyObject) {
let recorder = RPScreenRecorder.sharedRecorder()
guard recorder.available else{
print("Cannot record the screen")
return
}
recorder.delegate = self
recorder.startRecordingWithMicrophoneEnabled(true) { (err) in
guard err == nil else{
if err!.code ==
RPRecordingErrorCode.UserDeclined.rawValue{
print("User declined app recording")
}
else if err!.code ==
RPRecordingErrorCode.InsufficientStorage.rawValue{
print("Not enough storage to start recording")
}
else{
print("Error happened = \(err!)")
}
return
}
print("Successfully started recording")
self.recordBtn.enabled = false
self.stopRecordBtn.enabled = true
}
}
Which seems to work with the printing Successfully started recording.
However, when the button connected to the IBAction to stop recording is pressed the following code should run:
@IBAction func stop() {
let recorder = RPScreenRecorder.sharedRecorder()
print("1. before the recorder function")// This prints
recorder.stopRecordingWithHandler{controller, err in
guard let previewController = controller where err == nil else {
self.recordBtn.enabled = true
self.stopRecordBtn.enabled = false
print("2. Failed to stop recording")// This does not prints
return
}
previewController.previewControllerDelegate = self
self.presentViewController(previewController, animated: true,
completion: nil)
}
}
But nothing happens except to print out the first log ("1. before the recorder function"). I get non of the other log statements nor do the buttons toggle their enabled status.
I know the IBAction is connected due to hitting the statement but no idea why I can't get the stopRecordingWithHandler to fire.
I am testing this on an iPad Pro 9.7" running iOS 9.3.
I am starting to wonder if it has anything to do with trying to record a WKWebView but would imagine that I would get an error if this was the problem.
Any help would be greatly appreciated :)
I suspect that if you were to set a breakpoint anywhere inside your guard
statement (within stopRecordingCompletionHandler
), it would not crash your program or enter the debugger because the else
clause of your guard
statement is never being called.
In fact, this is expected behavior. We would not expect the else
clause to execute unless either controller is equal to nil
and therefore cannot be bound to the constant previewController
or error
exists and therefore does not equal nil
.
With guard
, the only way the else
clause will be called is if the specified conditions are NOT true. Your print statement in the startRecordingWithMicrophoneEnabled
closure is being called because it is sitting outside of the guard
statement.
So you just need to move some of that logic out of the else
clause. You do still want to handle errors there though.
recorder.stopRecordingWithHandler{controller, err in
guard let previewController = controller where err == nil else {
print("2. Failed to stop recording with error \(err!)") // This prints if there was an error
return
}
}
self.recordBtn.enabled = true
self.stopRecordBtn.enabled = false
previewController.previewControllerDelegate = self
self.presentViewController(previewController, animated: true,
completion: nil)
print("stopped recording!")
So just to be sure we're clear on the guard
syntax, it's:
guard <condition> else {
<statements to execute if <condition> is not true>
}
In your example, you're combining guard
with optional binding and a where
clause, to create the following situation:
controller
is not nil
, it will be bound to a constant called previewController
.nil
then we stop evaluating , never create the constant previewController
, and escape to the else
clause, which must transfer control with a keyword such as return
.controller
is not nil
and our constant has been created then we will go ahead and check our where
clause.where
evaluates to true
(so if there is no error), we will pass the test and be done with the guard
statement. else
will never be executed.
where
evaluates to false
, we will execute the else
block and anything after the guard
statement will not be called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With