mattrubin/OneTimePassword

CocoaPod-swift3-version and Carthage-swift3-version both not running out-of-the-box

Closed this issue · 4 comments

Hi there,

Great that you have rewritten OneTimePassword to work on Swift 3. Unfortunately we discovered some problems with the implementation of this library. Both for the CocoaPod as the Carthage version I got different errors.

First: the CocoaPod version.
When using the CocoaPod version, adjustments have to be made on the example-code of the generator in order to get the code running:

Statement in Podfile:
pod 'OneTimePassword', '~> 3.0'

The example code:

let name = "..."
let issuer = "..."
let secretString = "..."

guard let secretData = Data(base32String: secretString),
    !secretData.isEmpty else {
        print("Invalid secret")
        return nil
}

When trying to run this, the following error will be provided:
Argument labels '(base32String:)' do not match any available overloads

The adjusted code in order to get it running with the CocoaPod version:

let name = "..."
let issuer = "..."
let secretString = "..."

guard let secretData = NSData(base32String: secretString),
    secretData.length > 0 else {
        print("Invalid secret")
        return ""
}

Additionally, also one adjustment had to be made in the BridgingHeader:

#import "Base32/MF_Base32Additions.h"

Most likely, it now works like a charm.

Second: the Carthage version.

Statement in Cartfile
github "mattrubin/OneTimePassword" ~> 3.0

When using the Carthage version, the code does run out of the box as described in the example except for that the module "OneTimePassword" is missing the module CommonCrypto. We discovered that this problem occurs when trying to run the code on a simulator. There are workarounds like here . Running it on a device should be no problem, the problem is running it on a simulator.

Could you perhaps take a look at this? I still think OneTimePassword is a great library.

Base32 decoding (your CocoaPods issue):

The Base32 encoding and decoding is intentionally not exposed in the OneTimePassword bridging header because it is not functionality provided by this library. It's a part of the Base32 library which is a dependency of OneTimePassword. Instead of adding the Base32 header to OneTimePassword's bridging header, you should simply be able to add import Base32 at the top of any file where you need this functionality.

You're correct that the example code isn't quite right. The Base32 decoding initializer isn't bridged from NSData to Data. You can either use NSData(base32String: secretString) to initialize an NSData! and then bridge it explicitly to Data, or use MF_Base32Codec.data(fromBase32String: secretString) which returns an already-bridged Data!. I've improved this part of the README in #134.

(I'm also looking into replacing the existing Base32 dependency with a library that exposes a more Swift-friendly API – see #135)

CommonCrypto module map (your Carthage issue):

The project already uses custom modulemap files to access the CommonCrypto headers. This has been working via Carthage since OneTimePassword 2.0, and I don't think any of my recent changes would have broken it. What sort of problem are you seeing? A compiler error for OneTimePassword? A compiler error for your project? A runtime error? I can't tell what's wrong without more information.

Sorry for the late response. Hereby my findings.

Base 32 decoding (CocoaPods)
Adding the Base32 header to the bridging-header of the app is indeed not necessary. By adding import Base32 at the top of the file where it needs to be used in combination with NSData(base32String: secretString) which is bridged to Data for the Generator works perfect for now when using the CocoaPod.

Your other method, using MF_Base32Codec.data(fromBase32String: secretString) works also like a charm.

CommonCrypto (Carthage issue)
I've been using the CocoaPod since OneTimePassword 2.0 so I'm not sure if something broke since the release of 3.0. The thing I experienced is the following:

Missing required module 'CommonCrypto'

Simply importing CommonCrypto before importing OneTimePassword does not solve this problem.

For me using the CocoaPod version works like a charm, but I was not able to use the Carthage version. For it is no problem, but perhaps others experience the same problems.

I haven't been able to reproduce the issue with Carthage builds not finding CommonCrypto.

The compiler error you mention would appear if the compiler couldn't find the custom modulemaps referenced in the framework's SWIFT_INCLUDE_PATHS build setting. It sounds like you're building OneTimePassword by including the project in your workspace (rather than including a Carthage-built framework), so I recommend checking that the OneTimePassword build settings correctly reference the custom modulemaps, and ensuring that the CommonCrypto header exists at the path in the modulemap.

Since I can't reproduce this error and you seem to be using the library successfully via CocoaPods, I'm going to close the issue. Please feel free to reply with more information if you continue to have problems.