对象存储

  • 对象存储 > SDK 下载 > Objective-C SDK

    Objective-C SDK

    最近更新时间: 2024-08-05 18:23:52

    Objective-C SDK 为客户端 SDK,没有包含 token 生成实现,为了安全,token 都建议通过网络从服务端获取 具体生成代码可以参考七牛服务端官方 SDK 。支持 Mac 和 iOS,会根据文件大小自动选择表单上传还是断点续上传。

    版本

    Qiniu SDK 版本 最低 iOS 版本 最低 OS X 版本 Notes
    8.8.x iOS 9 OS X 10.15 Xcode 最低版本 11.
    8.7.x iOS 9 OS X 10.15 Xcode 最低版本 11.
    8.6.x iOS 9 OS X 10.15 Xcode 最低版本 11.
    8.5.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    8.4.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    8.3.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    8.2.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    8.1.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    8.0.x iOS 7 OS X 10.15 Xcode 最低版本 11.
    7.4.x iOS 7 OS X 10.9 Xcode 最低版本 6.
    7.3.x iOS 7 OS X 10.9 Xcode 最低版本 6.
    7.2.x iOS 7 OS X 10.9 Xcode 最低版本 6.
    7.1.x / AFNetworking-3.x iOS 7 OS X 10.9 Xcode 最低版本 6.
    7.0.x / AFNetworking-2.x iOS 6 OS X 10.8 Xcode 最低版本 5.
    7.x / AFNetworking-1.x iOS 5 OS X 10.7 Xcode 最低版本 5.
    6.x iOS 6 None Xcode 最低版本 5.

    1 安装

    1.1 使用 Cocoapods 进行安装

    pod "Qiniu", "~> 8.8.0"
    

    1.2 通过 Swift Package Manager

    App 对接:
    File -> Swift Packages -> Add Package Dependency,输入库链接,选择相应版本即可。
    库链接: https://github.com/qiniu/objc-sdk
    
    库对接:
    let package = Package(
        dependencies: [
            .package(url: "https://github.com/qiniu/objc-sdk", from: "8.8.0")
        ],
        // ...
    )
    
    库引入方式:
    import QiniuSDK
    

    2 推荐的使用姿势

    iOS SDK 作为移动端的 SDK,在使用时会被嵌入到移动端的应用中,为了保证信息的安全以及业务的灵活性,我们给出以下几点建议:

    2.1 AccessKey 和 SecretKey 下发

    账户以及 iam 子账户的密钥对 AccessKey 和 SecretKey 不要固化在客户端中,其涉及相关参数通过用户自己的业务服务端来生成并下发(比如上传的 Token)。业务服务端集中管理 AccessKey 和 SecretKey ,避免泄漏;其次 AccessKey 、SecretKey 和客户端应用需解耦,其因泄露更换时不会产生不必要麻烦。

    2.2 上传域名下发,并可以下发多个域名

    SDK 上传过程:

    1. 获取七牛 Bucket 的上传域名;
      • 指定域名。通过指定区域 id 或直接给上传域名列表方式指定域名,详情见 域名配置 QNFixedZone;
      • SDK 自动查询域名。SDK 内部自动调用七牛服务端接口,查询 Bucket 的上传域名,详情见 域名配置 QNAutoZone;
    2. 使用上传域名进行上传,上传过程会伴随主备重试,既多个域名时,一个域名上传失败,会尝试使用其他域名进行上传。

    建议的上传域名下发方式

    用户服务在下发上传 Token 时同时下发上传域名(可以在 App 需要进行上传时,先请求获取获取上传 Token 及上传域名),可下发多个域名,App 在拿到 Token 和上传域名后,配置上传 Config 以及 QNUploadManager,进而进行上传操作。

    具体代码示例如下:

    // Upload_Domain1, Upload_Domain2 为服务下发的上传域名
    QNFixedZone *fixedZone = [[QNFixedZone alloc] initWithUpDomainList:@[@"Upload_Domain1", @"Upload_Domain2"]];
    QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        builder.zone = fixedZone;
    }];
    QNUploadManager *manager = [[QNUploadManager alloc] initWithConfiguration:config];
    

    域名下发的优点:

    1. 跳过域名查询过程,上传更高效。
    2. 避免在 App 硬编码上传域名,导致使用不灵活,比如:
      • 在客户更换/增加区域时,由于 App 硬编码了区域,已发布的 App 无法处理此问题。
      • 某些客户生产环境使用的 Bucket 和 测试环境使用的 Bucket 不在同一个区域,在实际上线时错用了测试 Bucket 的区域,导致 Bucket 和区域不匹配,App 相关功能不可用。
      • 自定义域名,由于硬编码,老版本 App 也无法灵活应对。

    除了上面的问题,还有很多情景不再列举,上面问题的根本原因是由于 App 硬编码了区域的上传域名导致 App 不能灵活应对上传域名需要修改的场景,所以建议客户通过服务下发上传的方式来配置 SDK 的上传域名, 而不是直接硬编码上传域名。

    3 域名配置

    域名配置分为 QNFixZone 和 QNAutoZone 两种方式。

    3.1 QNFixZone

    在 QNFixZone 中,上传域名被固定,且不可更改。有两种配置方式:

    3.1.1 通过指定上传区域 ID 方式

    区域 ID 和区域域名对应关系参考 这里

    // 指定上传区域为 华东-浙江
    QNFixedZone *zone = [QNFixedZone createWithRegionId:@"z0"];
    

    这种方式硬编码了上传域名的区域,且不可更改,所以不建议在生产环境中使用,仅供测试使用。

    3.1.2 直接配置上传域名

    直接配置上传域名的方式可以灵活配置域名,我们不建议上传域名配置为固定域名,而是通过服务下发的方式进行配置。具体上传域名下发请参考上传域名下发介绍。

    // Upload_Domain1, Upload_Domain2 为服务下发的上传域名
    QNFixedZone *fixedZone = [[QNFixedZone alloc] initWithUpDomainList:@[@"Upload_Domain1", @"Upload_Domain2"]];
    

    3.2 QNAutoZone

    如果用户不想关心上传域名相关的逻辑,而且没有任何自定义的需求,完全依赖七牛的上传域名,则可以使用 AutoZone。AutoZone 相对于 FixZone 来说,在第一次上传时查询上传域名,后续会使用缓存的上传域名进行上传。在缓存有效期内不会更换上传域名,当前域名缓存有效期为 24 小时。
    示例代码:

    // 不指定 uc 域名,使用七牛公有云默认域名
    QNAutoZone *zone = [[QNAutoZone alloc] init];
    
    // 指定 uc 域名,公有云无需指定
    QNAutoZone *zone = [QNAutoZone zoneWithUcHosts:@[@"UCHost0", @"UCHost1"]];
    

    不过我们推荐用户使用上传域名下发的方式来配置上传域名,防止后续业务变更需要。

    4 上传

    4.1 上传示例

    SDK 内置两种上传方式:表单上传和分片上传,并根据具体情况,内部做了自动切换。表单上传使用一个 HTTP POST 请求完成文件的上传,因此比较适合较小的文件和较好的网络环境。相比而言,分片上传更能适应不稳定的网络环境,也比较适合上传比较大的文件(例如数百 MB 或更大)。

    若需深入了解上传方式之间的区别,请参阅上传类型中 表单上传分片上传 v1 版分片上传 v2 版 接口说明。

    QNUploadManager 上传接口参数说明:

    参数 类型 说明
    data NSData */NSString */PHAsset */PHAssetResource * 数据,可以是 NSData、文件路径、资源、数据流
    key NSString * 保存在服务器上的资源唯一标识,请参阅 键值对
    token NSString * 服务器分配的 token
    completionHandler QNUpCompletionHandler 上传回调函数,必填
    option QNUploadOption 如果需要进度通知、中途取消、指定 mimeType,则需要填写相应字段,详见下面的 QNUploadOption 参数说明

    QNUploadOption 参数说明:

    参数 类型 说明
    params NSDictionary<NSString *, NSString *> * 自定义变量,key 必须以 x: 开始
    metaDataParam NSDictionary<NSString *, NSString *> * 自定义meta数据,key 必须以 x-qn-meta- 开始
    mimeType NSString 指定文件的 mimeType
    progressHandler QNUpProgressHandler 上传进度回调
    #import <QiniuSDK.h>
    
    QNConfiguration *configuration = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        // 配置上传区域,Host0、Host1 建议通过服务方式下发
        builder.zone = [[QNFixedZone alloc] initWithUpDomainList:@[@"Host0", @"Host2"]];
        // 分片上传阈值:4MB,大于 4MB 采用分片上传,小于 4MB 采用表单上传
        builder.putThreshold = 4*1024*1024;
        // 开启并发分片上传
        builder.useConcurrentResumeUpload = true;
        // 使用分片 V2
        builder.resumeUploadVersion = QNResumeUploadVersionV2;
        // 文件分片上传时断点续传信息保存,表单上传此配置无效
        NSString *recorderPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
        builder.recorder = [QNFileRecorder fileRecorderWithFolder:recorderPath error:nil];
    }];
    QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:configuration];
    
    __weak typeof(self) weakSelf = self;
    QNUploadOption *uploadOption = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) {
        NSLog(@"percent == %.2f", percent);
    }
                                                                 params:nil
                                                               checkCrc:NO
                                                     cancellationSignal:^BOOL{
        // 当需要取消时,此处返回 true,SDK 内部会多次检查返回值,当返回值为 true 时会取消上传操作
        return false;
    }];
    
    NSString *filePath = @"";    // 文件路径
    NSString *key = @"";         // 文件 key
    NSString *uploadToken = @""; // 上传的 Token
    [upManager putFile:filePath key:key token:uploadToken complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
        if (info.isOK) {
            // 上传成功
        } else {
            // 上传失败
        }
    } option:uploadOption];
    

    4.2 上传配置介绍

    4.2.1 开启传输加速

    默认情况下,SDK 未开启使用加速域名上传的功能,如需开启需按下面方式进行配置:

    // 1. 在七牛云存储控制台修改 Bucket 配置,域名管理 -> 开启传输加速(SDK 开启使用加速域名上传的功能仅仅是 SDK 支持
    //    使用加速域名,所以要想使用传输加速,七牛云服务端需开启此功能)
    // 
    // 2. SDK 配置 
    // 方式一:使用 QNFixZone 配置
    QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        // Upload_Domain1 和 Upload_Domain2 为加速域名,可以参考七牛云存储控制台域名管理页面,建议通过用户服务下发,不要硬编码
        builder.zone =  [[QNFixedZone alloc] initWithUpDomainList:@[@"Upload_Domain1", @"Upload_Domain2"]];
    }];
    
    // 方式二:使用 AutoZone(v8.8.0 开始支持)
    QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        builder.accelerateUploading = YES;        // 开启传输加速,此参数仅对使用 QNAutoZone 时有效
        builder.zone = [[QNAutoZone alloc] init]; // 默认是 AutoZone,所以 zone 也可以不配置
    }];
    

    4.2.2 其他配置

    QNConfiguration *configuration = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
        builder.zone = [[QNAutoZone alloc] init]; // 配置上传区域,使用 QNAutoZone
        builder.recorderKeyGen = ^NSString *(NSString *uploadKey, NSString *filePath) {
            // 自定义 文件分片上传时断点续传信息保存的 key,默认使用 uploadKey
            return [NSString stringWithFormat:@"%@-%@", uploadKey, filePath];
        };
        // 文件分片上传时断点续传信息保存,表单上传此配置无效
        NSString *recorderPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
        builder.recorder = [QNFileRecorder fileRecorderWithFolder:recorderPath error:nil];
        // 文件采用分片上传时,分片大小为 2MB
        builder.chunkSize = 2*1024*1024;
        
        // 分片上传阈值:4MB,大于 4MB 采用分片上传,小于 4MB 采用表单上传
        builder.putThreshold = 4*1024*1024;
        
        // 单个域名/IP请求失败后最大重试次数为 1 次
        builder.retryMax = 1;
        
        // 重试时间间隔:0.5s
        builder.retryInterval = 0.5;
        
        // 请求超时时间:60s
        builder.timeoutInterval = 60;
        
        // 使用 HTTPS
        builder.useHttps = true;
        
        // 使用备用域名进行重试
        builder.allowBackupHost = true;
        
        // 开启加速上传
        builder.accelerateUploading = true;
       
        // 开启并发分片上传
        builder.useConcurrentResumeUpload = true;
        
        // 使用并发分片上传时,一个文件并发上传的分片个数
        builder.concurrentTaskCount = 2;
        
        // 使用分片 V2
        builder.resumeUploadVersion = QNResumeUploadVersionV2;
    }];
    
    
    // 指定文件 mime type
    NSString *mimeType = @"";
    // 用于服务器上传回调通知的自定义参数,参数的key必须以x: 开头  eg: x:foo
    NSDictionary <NSString *, NSString *> * params = @{};
    // 用于设置meta数据,参数的key必须以x-qn-meta- 开头  eg: x-qn-meta-key
    NSDictionary <NSString *, NSString *> * metaDataParams = @{};
    BOOL checkCrc = true;
    QNUploadOption *option = [[QNUploadOption alloc] initWithMime:mimeType
                                              byteProgressHandler:^(NSString *key, long long uploadBytes, long long totalBytes) {
        // 处理上传进度
    } params:params metaDataParams:metaDataParams checkCrc:checkCrc cancellationSignal:^BOOL{
        // 当需要取消时,此处返回 false,SDK 内部会不间断检测此返回值
        return false;
    }];
    
    // 关闭 DNS 预解析
    //从 7.4.0 开始增加了 DNS 预解析和缓存策略(每 2 分钟(进程非挂起状态)会自动刷新缓存策略)来减少 DNS 解析错误。默认预解析开启,需获取 IP 信息。
    kQNGlobalConfiguration.isDnsOpen = NO;
    
    // 关闭网络状态检测,当因网络异常而失败时,会检测网络状态,进而根据情况调整重试逻辑。默认开启网络状态检测。
    kQNGlobalConfiguration.connectCheckEnable = NO;
    

    5 下载文件

    该 SDK 并未提供下载文件相关的功能接口,因为文件下载是一个标准的 HTTP GET 过程。开发者只需理解资源 URI 的组成格式即可非常方便的构建资源 URI,并在必要的时候加上 下载凭证 ,即可使用 HTTP GET 请求获取相应资源。

    从安全性和代码可维护性的角度考虑,我们建议下载 URL 的拼接过程也在业务服务器进行,让客户端从业务服务器请求。

    API 参考

    常见问题

    • 如果碰到 crc 链接错误,请把 libz.dylib 加入到项目中去。
    • 如果碰到 res_9_ninit 链接错误,请把 libresolv.dylib 加入到项目中去。
    • 如果需要支持 iOS 5 或者支持 RestKit,请用 AFNetworking 1.x 分支的版本。
    • 如果碰到其他编译错误,请参考 Cocoapods 的troubleshooting
    • iOS 9+ 强制使用 https ,需要在 project build info 添加 NSAppTransportSecurity 类型 Dictionary。在 NSAppTransportSecurity下添加 NSAllowsArbitraryLoads 类型 Boolean ,值设为 YES。具体操作请查阅这里

    相关资源

    如果您有任何关于我们文档或产品的建议和想法,欢迎您通过以下方式与我们互动讨论:

    • 技术论坛 - 在这里您可以和其他开发者愉快的讨论如何更好的使用七牛云服务
    • 提交工单 - 如果您的问题不适合在论坛讨论或希望及时解决,您也可以提交一个工单,我们的技术支持人员会第一时间回复您
    • 博客 - 这里会持续更新发布市场活动和技术分享文章
    • 微博
    • 常见问题

    贡献代码

    1. Fork

    2. 创建您的特性分支 git checkout -b my-new-feature

    3. 提交您的改动 git commit -am ‘Added some feature’

    4. 将您的修改记录提交到远程 git 仓库 git push origin my-new-feature

    5. 然后到 github 网站的该 git 远程仓库的 my-new-feature 分支下发起 Pull Request

    许可证

    Copyright © 2020 qiniu.com

    基于 MIT 协议发布:

    以上内容是否对您有帮助?
  • Qvm free helper
    Close