bitpay / cordova-plugin-qrscanner

A fast, energy efficient, highly-configurable QR code scanner for Cordova apps and the browser.
MIT License
573 stars 777 forks source link

iOS can't compile on Xcode 10.2.1 Swift 5/4.2/4 #259

Closed matthprost closed 1 year ago

matthprost commented 5 years ago

Hi!

I can't compile this cordova plugin on Xcode 10.2.1 and I tried with Swift 5/4.2 and 4.

/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:483:16: warning: unnecessary check for 'iOS'; enclosing scope ensures guard will always be true
            if #available(iOS 8.0, *) {
               ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:470:9: note: enclosing scope here
        if #available(iOS 10.0, *) {
        ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:33:37: error: value of optional type 'AVCaptureConnection?' must be unwrapped to refer to member 'videoOrientation' of wrapped base type 'AVCaptureConnection'
            self.videoPreviewLayer?.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation);
                                    ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:33:37: note: chain the optional using '?' to access member 'videoOrientation' only for non-'nil' base values
            self.videoPreviewLayer?.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation);
                                    ^
                                              ?
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:33:37: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
            self.videoPreviewLayer?.connection.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation);
                                    ^
                                              !
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:89:64: error: argument of '#selector' refers to instance method 'pageDidLoad()' that is not exposed to Objective-C
        NotificationCenter.default.addObserver(self, selector: #selector(pageDidLoad), name: NSNotification.Name.CDVPageDidLoad, object: nil)
                                                               ^         ~~~~~~~~~~~
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:249:10: note: add '@objc' to expose this instance method to Objective-C
    func pageDidLoad() {
         ^
    @objc 
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:124:57: error: incorrect argument label in call (have 'forMediaType:', expected 'for:')
        let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
                                                        ^~~~~~~~~~~~~
                                                         for
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:136:68: error: incorrect argument label in call (have 'withMediaType:', expected 'for:')
                let availableVideoDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo)
                                                                   ^~~~~~~~~~~~~~
                                                                    for
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:154:43: error: value of optional type 'AVCaptureMetadataOutput?' must be unwrapped to a value of type 'AVCaptureMetadataOutput'
                captureSession!.addOutput(metaOutput)
                                          ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:154:43: note: coalesce using '??' to provide a default when the optional value contains 'nil'
                captureSession!.addOutput(metaOutput)
                                          ^
                                                     ?? <#default value#>
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:154:43: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
                captureSession!.addOutput(metaOutput)
                                          ^
                                                    !
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:157:80: error: value of optional type 'AVCaptureSession?' must be unwrapped to a value of type 'AVCaptureSession'
                captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                                                                               ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:157:80: note: coalesce using '??' to provide a default when the optional value contains 'nil'
                captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                                                                               ^
                                                                                              ?? <#default value#>
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:157:80: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
                captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                                                                               ^
                                                                                             !
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:257:57: error: incorrect argument label in call (have 'forMediaType:', expected 'for:')
        let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
                                                        ^~~~~~~~~~~~~
                                                         for
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:260:42: error: incorrect argument label in call (have 'forMediaType:completionHandler:', expected 'for:completionHandler:')
            AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (granted) -> Void in
                                         ^~~~~~~~~~~~~
                                          for
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:308:35: error: value of optional type 'AVCaptureConnection?' must be unwrapped to refer to member 'isEnabled' of wrapped base type 'AVCaptureConnection'
        captureVideoPreviewLayer?.connection.isEnabled = false
                                  ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:308:35: note: chain the optional using '?' to access member 'isEnabled' only for non-'nil' base values
        captureVideoPreviewLayer?.connection.isEnabled = false
                                  ^
                                            ?
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:308:35: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
        captureVideoPreviewLayer?.connection.isEnabled = false
                                  ^
                                            !
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:317:35: error: value of optional type 'AVCaptureConnection?' must be unwrapped to refer to member 'isEnabled' of wrapped base type 'AVCaptureConnection'
        captureVideoPreviewLayer?.connection.isEnabled = true
                                  ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:317:35: note: chain the optional using '?' to access member 'isEnabled' only for non-'nil' base values
        captureVideoPreviewLayer?.connection.isEnabled = true
                                  ^
                                            ?
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:317:35: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
        captureVideoPreviewLayer?.connection.isEnabled = true
                                  ^
                                            !
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:398:70: error: incorrect argument label in call (have 'forMediaType:', expected 'for:')
        let authorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo);
                                                                     ^~~~~~~~~~~~~
                                                                      for
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:422:52: error: value of optional type 'AVCaptureConnection?' must be unwrapped to refer to member 'isEnabled' of wrapped base type 'AVCaptureConnection'
            previewing = captureVideoPreviewLayer!.connection.isEnabled
                                                   ^
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:422:52: note: chain the optional using '?' to access member 'isEnabled' only for non-'nil' base values
            previewing = captureVideoPreviewLayer!.connection.isEnabled
                                                   ^
                                                             ?
/Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift:422:52: note: force-unwrap using '!' to abort execution if the optional value contains 'nil'
            previewing = captureVideoPreviewLayer!.connection.isEnabled
                                                   ^
                                                             !

** BUILD FAILED **

The following build commands failed:
    CompileSwift normal x86_64 /Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift
    CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler
(2 failures)
xcodebuild: Command failed with exit code 65

If I delete this plugin from cordova and compile again it will work perfectly fine. I'm using the last version available on NPM (3.0.1) of this plugin.

lennihanjohn commented 5 years ago

Same issue. unable to compile it with Qr-scanner plugin(3.0.1) and Xcode(10.2.1)

zhuzhengjing commented 5 years ago

Same issue.

            if #available(iOS 8.0, *) {
               ^
/Users/bruce/Documents/work/esky/app/esky-cordova/platforms/ios/eTracking/Plugins/cordova-plugin-qrscanner/QRScanner.swift:470:9: note: enclosing scope here
        if #available(iOS 10.0, *) {
        ^
/Users/bruce/Documents/work/esky/app/esky-cordova/platforms/ios/eTracking/Plugins/cordova-plugin-qrscanner/QRScanner.swift:136:62: warning: 'devices(for:)' was deprecated in iOS 10.0: Use AVCaptureDeviceDiscoverySession instead.
                let availableVideoDevices =  AVCaptureDevice.devices(for: AVMediaType.video)
                                                             ^
/Users/bruce/Documents/work/esky/app/esky-cordova/platforms/ios/eTracking/Plugins/cordova-plugin-qrscanner/QRScanner.swift:471:63: error: 'openSettingsURLString' has been renamed to 'UIApplicationOpenSettingsURLString'
            guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
                                                              ^~~~~~~~~~~~~~~~~~~~~
                                                              UIApplicationOpenSettingsURLString
UIKit.UIApplication:64:22: note: 'openSettingsURLString' was introduced in Swift 4.2
    public class let openSettingsURLString: String
                     ^
/Users/bruce/Documents/work/esky/app/esky-cordova/platforms/ios/eTracking/Plugins/cordova-plugin-qrscanner/QRScanner.swift:484:74: error: 'openSettingsURLString' has been renamed to 'UIApplicationOpenSettingsURLString'
                UIApplication.shared.openURL(NSURL(string: UIApplication.openSettingsURLString)! as URL)
                                                                         ^~~~~~~~~~~~~~~~~~~~~
                                                                         UIApplicationOpenSettingsURLString
UIKit.UIApplication:64:22: note: 'openSettingsURLString' was introduced in Swift 4.2
    public class let openSettingsURLString: String
lennihanjohn commented 5 years ago

ev

Hi Bruce, Please change UIApplication.openSettingsURLString to be UIApplicationOpenSettingsURLString and add this part <preference ` name="UseSwiftLanguageVersion" value="5" /> inside platform "ios"

marcelomiura commented 5 years ago

Hello! Does anyone has a solution for this issue?

azhengyongqin commented 5 years ago

@lennihanjohn Thanks, man! It solves my issue.

datnguyenthang commented 5 years ago

Hello, Is it official @lennihanjohn? I using Phonegap to build with this configure: <gap:plugin name="cordova-plugin-qrscanner" source="npm" spec="3.01" /> It throws error: The following build commands failed: CompileSwift normal x86_64 /Users/user/Documents/Mobile/platforms/ios/project/Plugins/cordova-plugin-qrscanner/QRScanner.swift CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler (2 failures) xcodebuild: Command failed with exit code 65 Does anyone has a solution for this issue?

SimoneMSR commented 5 years ago

@lennihanjohn I have tried your solution, but I still get the error. Here are my development settings ionic: 5.0.2 cordova: 9.0.0 gulp: 4.0.1 swift: 5.0.1 xcode : 10.2.1 macOS : 10.14.3

Could you help me?

I have also tried to run the plugin tests (via npm run gen-tests && npm run test:ios) but couldn't finish them since I get an error:

AssertionError [ERR_ASSERTION]: Task function must be specified
at Gulp.set [as _setTask] (/Users/mac/Progetti/soluzione1/qr-test/cordova-plugin-qrscanner/node_modules/undertaker/lib/set-task.js:10:3)
    at Gulp.task (/Users/mac/Progetti/soluzione1/qr-test/cordova-plugin-qrscanner/node_modules/undertaker/lib/task.js:13:8)
    at Object.<anonymous> (/Users/mac/Progetti/soluzione1/qr-test/cordova-plugin-qrscanner/gulpfile.js:22:6)
marcelomiura commented 5 years ago

The only thing that solved the issue on my case was to downgrade my xcode version, so I could generate the build without issues. Xcode Version: 10.1

lennihanjohn commented 5 years ago

@marcelomiura, I will try to downgrade the version of xcode tonight. If works, you will get a thumb up.

markterrill commented 5 years ago

Who is the maintainer on this project?

Open the Plugins/cordova-plugin-qrscanner/QRScanner.swift file.

Replace lines 469-490 with: @objc func openSettings(_ command: CDVInvokedUrlCommand) { if #available(iOS 10.0, *) { guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else { return } if UIApplication.shared.canOpenURL(settingsUrl) { UIApplication.shared.open(settingsUrl, completionHandler: { (success) in self.getStatus(command) }) } else { self.sendErrorCode(command: command, error: QRScannerError.open_settings_unavailable) } } else { // pre iOS 10.0 if #available(iOS 8.0, *) { UIApplication.shared.openURL(NSURL(string: UIApplicationOpenSettingsURLString)! as URL) self.getStatus(command) } else { self.sendErrorCode(command: command, error: QRScannerError.open_settings_unavailable) } } }

The key thing is fixing those two references to openSettingsURLString that cause issues.

Plugins/cordova-plugin-qrscanner/QRScanner.swift:471:63: error: 'openSettingsURLString' has been renamed to 'UIApplicationOpenSettingsURLString'

You'll see the altered lines on 484, 471.

markterrill commented 5 years ago

Have submitted pull request, https://github.com/bitpay/cordova-plugin-qrscanner/pull/271

devandanger commented 5 years ago

I opened the xcode project manually and corrected the following code for QRScanner someone would have to add this into the repo to work correctly. Note this is not that great of Swift it should not force unwrap like I'm doing here, much better way to write this, but it got me rolling again.

goldengel commented 4 years ago

Where to put?

<preference ` name="UseSwiftLanguageVersion" value="5" />

matthprost commented 4 years ago

Where to put?

<preference ` name="UseSwiftLanguageVersion" value="5" />

This can be put in your config.xml file at the root of your project. This file is generated by Cordova.

<preference name="SplashScreen" value="screen" />
<preference name="SplashScreenDelay" value="3000" />
<preference name="StatusBarOverlaysWebView" value="true" />
<preference name="UseSwiftLanguageVersion" value="5" />
michellecolin commented 4 years ago

The right way to write the preference is:

otherwise it was not working for me. Cordova 9

cmgustavo commented 4 years ago

Please, check this thread https://github.com/bitpay/cordova-plugin-qrscanner/issues/238#issuecomment-523886099

kcmatsuiweew commented 4 years ago

I tried to execute following steps in Xcode 11.

 ionic cordova plugin rm cordova-plugin-qrscanner
 ionic cordova plugin add cordova-plugin-qrscanner@3.0.1
 ionic cordova platform rm ios
 ionic cordova platform add ios@5
 ionic cordova build its

No errors on my side.

RonnieToupal07 commented 3 years ago

kcmatsuiweew solution worked for me in xcode 12!