我试图在Swift中编写一个HMAC类,首先在Objective C中编写它,然后使用Bridging-Header使该类可用于我的Swift代码。我很抱歉,如果我粘贴了太多代码,但我想知道为什么会这样,所以我可以更好地理解Swift和Objective C的接口,以及我如何解决错误I&# 39;得到。 " TBGHMAC.calculateWithAlgorithm:forKey:和Data:"函数产生一个"致命错误:无法解包Optional.None"错误。
从顶部开始,这是我的Swift代码中的代码片段,它调用Swift代码
let key : String = "" // start with empty string"
let data : String = "" // start with empty string"
let signature : String = TBGHMAC.calculateWithAlgorithm(HMACAlgorithm.SHA256, forKey: key, andData: data)
println(signature)
这是TBGHMAC头文件
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
@interface TBGHMAC : NSObject
typedef NS_ENUM(NSInteger, HMACAlgorithm)
{
SHA1,
MD5,
SHA256,
SHA384,
SHA512,
SHA224
};
+ (NSString *)calculateWithAlgorithm:(HMACAlgorithm)algorithm forKey:(NSString*)key andData:(NSString *)data;
+ (NSInteger)digestLengthForAlgorithm:(HMACAlgorithm)algorithm;
@end
最后这里是实现文件
+ (NSString *)calculateWithAlgorithm:(HMACAlgorithm)algorithm forKey:(NSString *)key andData:(NSString *)data
{
NSUInteger keyNumberOfBytes = [key lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
void *keyBuffer = malloc(keyNumberOfBytes);
NSUInteger keyUsedLength = 0;
NSRange keyRange = NSMakeRange(0, [key length]);
BOOL keyResult = [key getBytes:keyBuffer maxLength:keyNumberOfBytes usedLength:&keyUsedLength encoding:NSUTF8StringEncoding options:0 range:keyRange remainingRange:NULL];
NSUInteger dataNumberOfBytes = [data lengthOfBytesUsingEncoding:NSUnicodeStringEncoding];
void *dataBuffer = malloc(dataNumberOfBytes);
NSUInteger dataUsedLength = 0;
NSRange dataRange = NSMakeRange(0, [data length]);
BOOL dataResult = [data getBytes:dataBuffer maxLength:dataNumberOfBytes usedLength:&dataUsedLength encoding:NSUTF8StringEncoding options:0 range:dataRange remainingRange:NULL];
NSInteger digestLength = [self digestLengthForAlgorithm:algorithm];
unsigned char hmac[digestLength];
CCHmac(algorithm, &keyBuffer, strlen(keyBuffer), &dataBuffer, strlen(dataBuffer), &hmac);
NSData *hmacBytes = [NSData dataWithBytes:hmac length:sizeof(hmac)];
NSString* returnStr = [[NSString alloc] initWithData:hmacBytes encoding:NSUTF8StringEncoding];
free(keyBuffer);
free(dataBuffer);
return returnStr;
}
+ (NSInteger)digestLengthForAlgorithm:(HMACAlgorithm)algorithm
{
switch (algorithm)
{
case MD5: return CC_MD5_DIGEST_LENGTH;
case SHA1: return CC_SHA1_DIGEST_LENGTH;
case SHA224: return CC_SHA224_DIGEST_LENGTH;
case SHA256: return CC_SHA256_DIGEST_LENGTH;
case SHA384: return CC_SHA384_DIGEST_LENGTH;
case SHA512: return CC_SHA512_DIGEST_LENGTH;
default: return 0;
}
}
@end
请指出为什么会出现此错误,以及我如何解决它。我不明白这个错误是如何产生的,因为我没有使用任何Optionals,Xcode也没有试图纠正我使用Optionals。
答案 0 :(得分:1)
Objective-C方法
+ (NSString *)calculateWithAlgorithm:(HMACAlgorithm)algorithm forKey:(NSString*)key andData:(NSString *)data;
以暴露于Swift
class func calculateWithAlgorithm(algorithm: HMACAlgorithm, forKey key: String!, andData data: String!) -> String!
它返回(隐式解包)可选字符串,因为Objective-C方法返回的NSString
可能是nil
。
将返回值转换为
中的String
let signature : String = BGHMAC.calculateWithAlgorithm(...)
如果返回值为nil
(&#34;没有值&#34;),会导致运行时异常。因此,您应该测试返回值 在使用之前:
let signature : String! = TBGHMAC.calculateWithAlgorithm(HMACAlgorithm.SHA256, forKey: key, andData: data)
if signature {
println(signature)
} else {
println("failed")
}
但为什么calculateWithAlgorithm()
会返回nil
?问题出在这里:
NSString* returnStr = [[NSString alloc] initWithData:hmacBytes encoding:NSUTF8StringEncoding];
消息摘要是一个非常随意的字节序列,无法解释
因此,作为UTF-8字符串,returnStr
为零。
要解决您的问题,您可以将消息摘要转换为 使用 Base64编码的字符串:
NSString* returnStr = [hmacBytes base64EncodedStringWithOptions:0];