项目标题与描述
Aliyun OSS iOS SDK 是阿里云官方提供的 iOS 客户端开发工具包,用于访问和管理阿里云对象存储服务(OSS)。该 SDK 提供了简单易用的 API,支持文件上传、下载、删除等基本操作,同时支持断点续传、分片上传、CRC64校验等高级功能。
主要特点:
- 支持 iOS 8.0 及以上系统
- 提供 Objective-C 和 Swift 两种语言的示例代码
- 支持直接引入 Framework 或通过 CocoaPods 集成
- 兼容 IPv6-only 网络环境
- 提供完善的错误处理和日志功能
功能特性
- 文件上传:支持普通上传、追加上传、分片上传和断点续传
- 文件下载:支持普通下载和范围下载
- 文件管理:支持文件复制、删除、获取文件元信息等
- Bucket 管理:支持 Bucket 的创建、删除、权限设置等
- 高级功能:
- CRC64 校验保证数据传输完整性
- HTTPDNS 防止域名劫持
- 支持后台传输服务
- 支持自定义域名(CNAME)
- 安全特性:
- 支持 STS 临时凭证访问
- 支持签名验证
- 支持 HTTPS
安装指南
CocoaPods 安装
在 Podfile 中添加以下依赖:
pod 'AliyunOSSiOS'
然后运行 pod install
命令。
手动集成 Framework
- 克隆项目:
git clone git@github.com:aliyun/aliyun-oss-ios-sdk.git
- 进入项目目录并执行打包脚本:
cd aliyun-oss-ios-sdk
sh ./buildiOSFramework.sh
- 生成的 Framework 位于 Products 目录下,将其拖入 Xcode 项目中
系统要求
- iOS 8.0 及以上系统
- Xcode 8 及以上版本
- 需要添加以下系统库:
- libresolv.tbd
- SystemConfiguration.framework
- CoreTelephony.framework
使用说明
初始化客户端
#import <AliyunOSSiOS/AliyunOSSiOS.h>
NSString *endpoint = "yourEndpoint";
id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:@"yourAccessKey" secretKey:@"yourSecretKey"];
OSSClientConfiguration *conf = [OSSClientConfiguration new];
conf.maxRetryCount = 3;
conf.timeoutIntervalForRequest = 30;
conf.timeoutIntervalForResource = 24 * 60 * 60;
OSSClient *client = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credential clientConfiguration:conf];
上传文件示例
OSSPutObjectRequest *put = [OSSPutObjectRequest new];
put.bucketName = @"bucketName";
put.objectKey = @"objectKey";
put.uploadingFileURL = [NSURL fileURLWithPath:@"filePath"];
put.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
NSLog(@"%lld, %lld, %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend);
};
OSSTask *putTask = [client putObject:put];
[putTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"upload object success!");
} else {
NSLog(@"upload object failed, error: %@" , task.error);
}
return nil;
}];
下载文件示例
OSSGetObjectRequest *request = [OSSGetObjectRequest new];
request.bucketName = @"bucketName";
request.objectKey = @"objectKey";
request.downloadProgress = ^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
NSLog(@"%lld, %lld, %lld", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
};
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"downloadFile"];
request.downloadToFileURL = [NSURL fileURLWithPath:filePath];
OSSTask *getTask = [client getObject:request];
[getTask continueWithBlock:^id(OSSTask *task) {
if (!task.error) {
NSLog(@"download object success!");
} else {
NSLog(@"download object failed, error: %@" , task.error);
}
return nil;
}];
核心代码
CRC64 校验实现
// NSMutableData+OSS_CRC.m
#import "NSMutableData+OSS_CRC.h"
#include "aos_crc64.h"
@implementation NSMutableData (OSS_CRC)
- (uint64_t)oss_crc64 {
return aos_crc64(0, self.mutableBytes, self.length);
}
@end
文件上传任务管理
// OSSClient.m
- (OSSTask *)upload:(OSSMultipartUploadRequest *)request
uploadIndex:(NSMutableArray *)alreadyUploadIndex
uploadPart:(NSMutableArray *)alreadyUploadPart
count:(NSUInteger)partCout
uploadedLength:(NSUInteger *)uploadedLength
fileSize:(unsigned long long)uploadFileSize {
NSUInteger bytesSent = 0;
NSUInteger partSize = request.partSize;
for (NSUInteger idx = 1; idx <= partCout; idx++) {
if ([alreadyUploadIndex containsObject:@(idx)]) {
bytesSent += partSize;
continue;
}
@autoreleasepool {
OSSUploadPartRequest *uploadPart = [OSSUploadPartRequest new];
uploadPart.bucketName = request.bucketName;
uploadPart.objectkey = request.objectKey;
uploadPart.uploadId = request.uploadId;
uploadPart.partNumber = idx;
uploadPart.uploadPartFileURL = request.uploadingFileURL;
uploadPart.partSize = partSize;
uploadPart.uploadPartOffset = bytesSent;
if (idx == partCout) {
uploadPart.partSize = uploadFileSize - bytesSent;
}
OSSTask *uploadPartTask = [self uploadPart:uploadPart];
[uploadPartTask waitUntilFinished];
if (uploadPartTask.error) {
return uploadPartTask;
}
OSSUploadPartResult *result = uploadPartTask.result;
[alreadyUploadPart addObject:result];
[alreadyUploadIndex addObject:@(idx)];
bytesSent += uploadPart.partSize;
*uploadedLength = bytesSent;
}
}
return [OSSTask taskWithResult:nil];
}
HTTPDNS 实现
// OSSHttpdns.m
- (NSString *)asynGetIpByHost:(NSString *)host {
IpObject *ipObject = [gHostIpMap objectForKey:host];
if (!ipObject) {
[self resolveHost:host];
return nil;
} else if ([[NSDate date] timeIntervalSince1970] - ipObject.expiredTime > MAX_ENDURABLE_EXPIRED_TIME_IN_SECOND) {
[self resolveHost:host];
return nil;
} else if (ipObject.expiredTime -[[NSDate date] timeIntervalSince1970] < PRERESOLVE_IN_ADVANCE_IN_SECOND) {
[self resolveHost:host];
return ipObject.ip;
} else {
return ipObject.ip;
}
}
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
公众号二维码