Scanning an invalid QR code shows an error dialog

* From the error dialog you are able to back out of scanning or try again. Adds English localization for this message.

  Adds an extra flag in OWSQRCodeScanningViewController to make sure that we don’t handle captureResults when capture is disabled (this was racing before because the call to [capture stop] is async and that was causing the cancel case to present the error dialog multiple times.

  Fixes Signal-iOS#1347

* Fixes appearance of race with starting capture
  Also marks the capture variable as atomic since it is accessed on
  multiple threads.

// FREEBIE
pull/1/head
Matthew Douglass 9 years ago committed by Michael Kirk
parent 40d6550fca
commit bbfffdf79f

@ -62,6 +62,37 @@ NS_ASSUME_NONNULL_BEGIN
// pragma mark - OWSQRScannerDelegate
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithString:(NSString *)string
{
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
if (!parser.isValid) {
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
NSString* title = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_TITLE", @"report an invalid linking code");
NSString* body = NSLocalizedString(@"LINK_DEVICE_INVALID_CODE_BODY", @"report an invalid linking code");
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
message:body
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction =
[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
}];
[alertController addAction:cancelAction];
UIAlertAction *proceedAction =
[UIAlertAction actionWithTitle:NSLocalizedString(@"LINK_DEVICE_RESTART", @"attempt another linking")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self.qrScanningController startCapture];
}];
[alertController addAction:proceedAction];
[self presentViewController:alertController animated:YES completion:nil];
} else {
NSString *title
= NSLocalizedString(@"LINK_DEVICE_PERMISSION_ALERT_TITLE", @"confirm the users intent to link a new device");
NSString *linkingDescription
@ -85,22 +116,16 @@ NS_ASSUME_NONNULL_BEGIN
[UIAlertAction actionWithTitle:NSLocalizedString(@"CONFIRM_LINK_NEW_DEVICE_ACTION", @"Button text")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self provisionWithString:string];
[self provisionWithParser:parser];
}];
[alertController addAction:proceedAction];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)provisionWithString:(NSString *)string
{
OWSDeviceProvisioningURLParser *parser = [[OWSDeviceProvisioningURLParser alloc] initWithProvisioningURL:string];
if (!parser.isValid) {
DDLogError(@"Unable to parse provisioning params from QRCode: %@", string);
return;
}
- (void)provisionWithParser:(OWSDeviceProvisioningURLParser *)parser
{
NSData *myPublicKey = [[TSStorageManager sharedManager] identityKeyPair].publicKey;
NSData *myPrivateKey = [[TSStorageManager sharedManager] identityKeyPair].ows_privateKey;
NSString *accountIdentifier = [TSStorageManager localNumber];
@ -123,7 +148,7 @@ NS_ASSUME_NONNULL_BEGIN
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:[self retryAlertControllerWithError:error
retryBlock:^{
[self provisionWithString:string];
[self provisionWithParser:parser];
}]
animated:YES
completion:nil];

@ -8,7 +8,7 @@
@interface OWSQRCodeScanningViewController ()
@property (nonatomic) BOOL captureEnabled;
@property (nonatomic, strong) ZXCapture *capture;
@property (atomic, strong) ZXCapture *capture;
@property UIView *maskingView;
@property CALayer *maskingLayer;
@ -97,14 +97,17 @@
dispatch_async(dispatch_get_main_queue(), ^{
[self.view.layer addSublayer:self.capture.layer];
[self.view bringSubviewToFront:self.maskingView];
[self.capture start];
});
});
}
} else {
[self.capture start];
}
}
- (void)stopCapture
{
self.captureEnabled = NO;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.capture stop];
});
@ -137,6 +140,8 @@
- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result
{
if (!self.captureEnabled)
return;
[self stopCapture];
// TODO bounding rectangle

Loading…
Cancel
Save