gpt4 book ai didi

swift - 无法打开 Optional.None 错误,但未使用 Optional

转载 作者:行者123 更新时间:2023-11-28 07:17:50 24 4
gpt4 key购买 nike

我试图在 Swift 中编写一个 HMAC 类,方法是首先在 Objective C 中编写它,然后使用 Bridging-Header 使该类可用于我的 Swift 代码。如果我粘贴了太多代码,我很抱歉,但我想了解为什么会这样,这样我就可以更好地理解 Swift 和 Objective C 的接口(interface),以及如何解决我遇到的错误。 “TBGHMAC.calculateWithAlgorithm:forKey:和数据:”函数产生“ fatal error :无法展开 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。

最佳答案

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(“无值”),则会导致运行时异常。因此,您应该测试返回值使用前:

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 为 nil。

要解决您的问题,您可以将消息摘要转换为使用 Base64 编码的字符串:

NSString* returnStr = [hmacBytes base64EncodedStringWithOptions:0];

关于swift - 无法打开 Optional.None 错误,但未使用 Optional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24614927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com