You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C与Swift编码结果不一致问题排查及解决方案咨询

Objective-C与Swift Base64编码结果不一致的原因及解决方案

嘿,我来帮你理清这个问题——你遇到的编码不一致根本不是Objective-C和Swift的Base64实现差异,而是输入的原始字符串本身就不一样!

一、问题根源:JSON键顺序导致原始字符串不同

先对比你给出的两个初始字符串:

Objective-C初始字符串:{"userType":2,"password":"qazwsx2","account":"15921810000"}
Swift初始字符串:"{\"userType\":2,\"account\":\"15921810000\",\"password\":\"qazwsx2\"}"

你会发现,JSON里的键顺序不一样:Objective-C是userType→password→account,Swift是userType→account→password。Base64是对原始二进制字节的直接编码,只要输入的字符串字节序列有差异,编码结果必然不同。而Objective-C和Swift的dataUsingEncoding:/data(using:)、Base64编码逻辑是完全一致的,问题出在输入源上。

二、最优解决办法:统一用JSON序列化生成字符串

手动拼接JSON字符串很容易出现这种键顺序不一致的问题,正确的做法是用系统的JSON序列化API生成字符串,这样能保证两边生成的二进制数据完全一致(iOS 13+/macOS 10.15+之后,JSONSerialization会按字典键的排序生成JSON,低版本虽然无序,但只要两边用同样的序列化逻辑,结果就会一致)。

Objective-C 正确实现代码

// 先构造参数字典,避免手动拼接字符串
NSDictionary *params = @{
    @"userType": @2,
    @"password": @"qazwsx2",
    @"account": @"15921810000"
};
NSError *error;
// 序列化生成标准JSON数据
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if (!error) {
    NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSData *encodeData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64Str = [encodeData base64EncodedStringWithOptions:0];
    // 此时base64Str会和Swift端完全一致
}

Swift 正确实现代码

// 构造相同的参数字典
let params: [String: Any] = [
    "userType": 2,
    "password": "qazwsx2",
    "account": "15921810000"
]
do {
    // 序列化生成标准JSON数据
    let jsonData = try JSONSerialization.data(withJSONObject: params, options: [])
    if let jsonStr = String(data: jsonData, encoding: .utf8) {
        let encodeData = jsonStr.data(using: .utf8)
        let base64Str = encodeData?.base64EncodedString(options: .init(rawValue: 0))
        // 此时base64Str会和Objective-C端完全一致
    }
} catch {
    print("JSON序列化失败:\(error)")
}

三、备选方案:Objective-C桥接调用

如果你因为历史代码限制,不能修改现有的字符串生成逻辑,可以通过桥接的方式,让Swift直接调用Objective-C的编码方法,确保逻辑完全一致:

  1. 创建Objective-C工具类

StringEncoder.h

#import <Foundation/Foundation.h>

@interface StringEncoder : NSObject
/// 将字符串UTF8编码后转Base64
+ (NSString *)base64EncodeWithUTF8String:(NSString *)inputStr;
@end

StringEncoder.m

#import "StringEncoder.h"

@implementation StringEncoder
+ (NSString *)base64EncodeWithUTF8String:(NSString *)inputStr {
    NSData *encodeData = [inputStr dataUsingEncoding:NSUTF8StringEncoding];
    return [encodeData base64EncodedStringWithOptions:0];
}
@end
  1. 配置Swift桥接文件
    在你的Swift项目中创建桥接文件(比如YourProjectName-Bridging-Header.h),并添加:
#import "StringEncoder.h"

(如果项目已有桥接文件,直接添加导入语句即可)

  1. 在Swift中调用
// 使用和Objective-C端完全一致的原始字符串
let originalStr = "{\"userType\":2,\"password\":\"qazwsx2\",\"account\":\"15921810000\"}"
let base64Str = StringEncoder.base64EncodeWithUTF8String(originalStr)
// 此时base64Str会和Objective-C端的结果完全相同

内容的提问来源于stack exchange,提问作者dengApro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:45:47