快速入门

最近更新时间:2025-11-04 11:34:42

我的收藏

相关资源

SDK 源码地址请参考:XML iOS SDK
SDK 快速下载地址:XML iOS SDK
示例 Demo 可参考:XML iOS SDK Demo
SDK 接口与参数文档请参见 SDK API 参考
SDK 文档中的所有示例代码请参见 SDK 代码示例
SDK 更新日志请参见:ChangeLog
SDK 常见问题请参见:iOS SDK 常见问题

环境配置与准备

1. 您需要一个 iOS 应用,这个应用可以是您现有的工程,也可以是新建的工程。
2. SDK 支持 iOS 8.0 及以上的版本,在安装前请检查您项目支持的最低系统版本。
3. 您需要获取一个腾讯云 API 密钥,该密钥是您使用 COS SDK 各项功能的前提。
说明:
密钥是向 COS 发起请求时的身份认证凭证,包括临时密钥和永久密钥。临时密钥 适用于前端直传等临时授权场景,永久密钥 适用于受信任的用户,安全性高的场景。
建议用户 使用临时密钥 调用 SDK,通过临时授权的方式进一步提高 SDK 使用的安全性。申请临时密钥时,请遵循 最小权限指引原则,防止泄露目标存储桶或对象之外的资源。
如果您一定要使用永久密钥,建议遵循 最小权限指引原则 对永久密钥的权限范围进行限制。

安装 SDK

方式一:使用 Cocoapods 集成(推荐)

COS SDK 有三个版本:标准版、精简版、无腾讯灯塔版。
标准版:包含了 COS API的所有功能,功能最为完善。
精简版:仅包含 COS 的文件上传/下载功能(如果您仅仅使用到上传和下载功能,并且对 SDK 体积要求较高,推荐使用精简版 SDK)。
无腾讯灯塔版:在标准版的基础上移除了腾讯的灯塔数据上报服务。
说明:
为了持续跟踪和优化 SDK 的质量,给您带来更好的使用体验,我们在 SDK 中引入了 腾讯灯塔 SDK,腾讯灯塔只对 COS 侧的请求性能进行监控不会上报业务侧数据。
在您工程的 Podfile 文件中添加:
标准版
精简版
无腾讯灯塔版
pod 'QCloudCOSXML'
pod 'QCloudCOSXML/Transfer'
pod 'QCloudCOSXML/Slim'
说明:
精简版 SDK 和无腾讯灯塔版 SDK 是通过 Cocoapods 的 Subspec 功能实现的,因此目前只支持通过自动集成的方式进行引入。
注意:
Swift 项目使用 Pod 集成时,需要在 podfile 文件中加上 use_frameworks!。
使用 Pod 集成 SDK 后,在编译时出现无权限写入问题,请在 Build Settings 中搜索 ENABLE_USER_SCRIPT_SANDBOXING 并设置为 NO ,如下图所示:


方式二:手动集成

我们在 SDK Releases 里提供了SDK 发布至今所有的正式包。集成方式参考如下:
1. 将 QCloudCOSXML.framework、QCloudCore.framework 、QCloudTrack.framework和 COSBeaconAPI_Base.framework 拖入到工程中。

说明:
QCloudCore.framework、QCloudCOSXML.framework 为 SDK 核心组件,必选。
COSBeaconAPI_Base.framework、QCloudTrack.framework 为日志上报组件,可选依赖。
2. 添加以下系统依赖:
CoreTelephony
Foundation
SystemConfiguration
libc++.tbd
3. 在项目Build Setting中设置 Other Linker Flags,添加以下参数:
-ObjC

说明:
SDK 提供了打包脚本,支持根据业务需求自行打包(该打包脚本依赖于 Cocoapods,请先确保您的开发环境安装了 Cocoapods)。打包步骤如下:
1. 下载源码:git clone https://github.com/tencentyun/qcloud-sdk-ios。
2. 运行打包脚本:source package.sh。
3. 将打包产物拖到工程中,然后按照上面手动集成的方式操作即可。
iOS:将 ios 文件夹下的产物拖入项目。
macOS:将 osx 文件夹下的产物拖入项目。


初始化 COS 服务

导入头文件

Objective-C
Swift
标准版
精简版
无腾讯灯塔版
#import <QCloudCOSXML/QCloudCOSXML.h>
#import <QCloudCOSXML/QCloudCOSXMLTransfer.h>
#import <QCloudCOSXML/QCloudCOSXML.h>
标准版
精简版
无腾讯灯塔版
import QCloudCOSXML
import QCloudCOSXML
import QCloudCOSXML

初始化 COS

说明:
在使用 COS SDK 之前,我们需要在控制台创建一个存储桶,创建指引请参见 控制台快速入门
在应用启动后,初始化 COS SDK。
Objective-C
Swift
SwiftUI
//AppDelegate.m
@interface AppDelegate()
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication * )application
didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
// 存储桶所在地域简称可以在控制台查看:https://console.cloud.tencent.com/cos5/bucket
// 例如广州地区是 ap-guangzhou,COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = @"COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
configuration.endpoint = endpoint;
// 初始化 COS 服务示例
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
configuration];
return YES;
}

@end
//AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = QCloudServiceConfiguration.init();
let endpoint = QCloudCOSXMLEndPoint.init();
// 存储桶所在地域简称可以在控制台查看:https://console.cloud.tencent.com/cos5/bucket
// 例如广州地区是 ap-guangzhou,COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = "COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
config.endpoint = endpoint;

// 初始化 COS 服务示例
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
with: config);
return true
}
}
import SwiftUI
import QCloudCOSXML

@main
struct SwiftUIDemoApp: App {
init() {
// 在应用初始化时调用 SDK 配置
COSManager.shared.setupCOSSDK();
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

class COSManager: NSObject {
static let shared = COSManager()
private override init() {}
func setupCOSSDK() {
let config = QCloudServiceConfiguration.init();
let endpoint = QCloudCOSXMLEndPoint.init();
// 存储桶所在地域简称可以在控制台查看:https://console.cloud.tencent.com/cos5/bucket
// 例如广州地区是 ap-guangzhou,COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = "COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
config.endpoint = endpoint;
// 初始化 COS 服务示例
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: config);
}
}

设置 API 访问密钥

访问密钥是 COS SDK 访问所有服务的前提,密钥分为:永久密钥和临时密钥。SDK 内部提供了诸多方法来设置密钥,具体如下:
临时密钥:和每一个 COS 请求关联,业务方在发起请求时进行设置,优先级高于使用回调设置密钥的方式。
密钥回调:SDK 会在首次和缓存的密钥快过期时以回调的方式重新获取访问密钥。
注意:
强烈建议用户 使用临时密钥 调用 SDK,通过临时授权的方式进一步提高 SDK 使用的安全性。申请临时密钥时,请遵循 最小权限指引原则,防止泄漏目标存储桶或对象之外的资源。
临时密钥
密钥回调
说明:
临时密钥和每一个 COS 请求进行关联。
临时密钥的优先级高于密钥回调的方式,如果同时设置了临时密钥和密钥回调的方式则优先使用临时密钥。
SDK 中所有的请求(Request)都支持通过 credential 属性来设置临时密钥。
若项目中全部使用临时密钥,则无需使用密钥回调的方式。
临时密钥 ID、Key、Token 的获取指引,请参见 临时密钥生成及使用指引
Objective-C
Swift
// 以文件上传请求为例
QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
QCloudCredential * credential = [QCloudCredential new];
// 临时密钥 ID
credential.secretID = @"secretID";
// 临时密钥 key
credential.secretKey = @"secretKey";
// 临时密钥 token
credential.token = @"token";
// 设置临时密钥
put.credential = credential;
// 本地文件路径
NSURL* url = [NSURL fileURLWithPath:@"文件的URL"];
// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
put.bucket = @"examplebucket-1250000000";
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = @"exampleobject";
//需要上传的对象内容。可以传入 NSData* 或者 NSURL* 类型的变量
put.body = url;
//监听上传进度
[put setSendProcessBlock:^(int64_t bytesSent,
int64_t totalBytesSent,
int64_t totalBytesExpectedToSend) {
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
}];

//监听上传结果
[put setFinishBlock:^(id outputObject, NSError *error) {
//可以从 outputObject 中获取 response 中 etag 或者自定义头部等信息
NSDictionary * result = (NSDictionary *)outputObject;
}];

[[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
// 以文件上传请求为例
let put:QCloudCOSXMLUploadObjectRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>();
let credential = QCloudCredential()
// 临时密钥 ID
credential.secretID = "secretID"
// 临时密钥 Key
credential.secretKey = "secretKey"
// 临时密钥 token
credential.token = "token"
// 设置临时密钥
put.credential = credential
// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
put.bucket = "examplebucket-1250000000";
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = "exampleobject";
//需要上传的对象内容。可以传入 NSData* 或者 NSURL* 类型的变量
put.body = NSURL.fileURL(withPath: "Local File Path") as AnyObject;

//监听上传结果
put.setFinish { (result, error) in
// 获取上传结果
if error != nil{
print(error!);
}else{
print(result!);
}
}

//监听上传进度
put.sendProcessBlock = { (bytesSent, totalBytesSent,
totalBytesExpectedToSend) in
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
};
//设置上传参数
put.initMultipleUploadFinishBlock = {(multipleUploadInitResult, resumeData) in
//在初始化分块上传完成以后会回调该 block,在这里可以获取 resumeData
//并且可以通过 resumeData 生成一个分块上传的请求
let resumeUploadRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>
.init(request: resumeData as Data?);
}

QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(put);


说明:
密钥回调支持:临时密钥、永久密钥、服务端计算签名等多种密钥形式。
在某些业务场景中,客户端请求与访问密钥并非严格遵循一对一的关系,可能存在多个请求共享同一密钥的情况。为降低业务方的集成复杂度与密钥管理负担,我们提供了密钥代理机制。通过该机制,业务方只需实现指定的代理接口(QCloudSignatureProvider),SDK 即可在每次发起网络请求时动态获取有效的访问密钥,极大简化了密钥的调用与管理流程。
此外业务方可能为保障密钥安全,不会将密钥直接下发至客户端,而是采用签名等安全策略进行权限管控。为此 SDK 同样支持在回调中以签名方式发起请求,允许业务方通过安全计算生成临时访问凭证,确保密钥在传输与使用过程中的安全性,同时满足企业级安全合规要求。
客户端管理密钥
服务端签名
Objective-C
Swift
SwiftUI
//AppDelegate.m
//AppDelegate 需遵循 QCloudSignatureProvider
@interface AppDelegate()<QCloudSignatureProvider>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication * )application
didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
endpoint.regionName = @"COS_REGION";
endpoint.useHTTPS = true;
configuration.endpoint = endpoint;
// 设置密钥回调代理
configuration.signatureProvider = self;
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
configuration];
return YES;
}


// 密钥回调的代理方法
- (void)signatureWithFields:(QCloudSignatureFields*)fileds
request:(QCloudBizHTTPRequest*)request
urlRequest:(NSMutableURLRequest*)urlRequst
compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
{
/**
* 此处获取密钥,如果使用永久密钥则忽略
* ...
*/
/**
* 此处既可以是临时密钥也可以是永久密钥
* 注意:永久密钥不可用于生产环境,仅可作为调试使用
*/
QCloudCredential* credential = [QCloudCredential new];
// 密钥 SecretId
credential.secretID = @"SECRETID";
// 密钥 SecretKey
credential.secretKey = @"SECRETKEY";
// 密钥 Token(如果使用永久密钥不需要填入 token,如果使用临时密钥需要填入)
credential.token = @"TOKEN";
// 强烈建议返回服务器时间作为签名的开始时间, 用来避免由于用户手机本地时间偏差过大导致的签名不正确(参数 startTime 和 expiredTime 单位为秒)
credential.startDate = [NSDate dateWithTimeIntervalSince1970:startTime]; // 单位是秒
credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:expiredTime]];// 单位是秒
QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
initWithCredential:credential];
// SDK 中默认下面所有 Header 都参与签名,无需设置。
// 若需制定某个 Header 不参与签名,则将相应的 Header 从下面数组中删除,然后赋值给 shouldSignedList 即可。
// creator.shouldSignedList = @[@"Cache-Control", @"Content-Disposition", @"Content-Encoding", @"Content-Length", @"Content-MD5", @"Content-Type", @"Expect", @"Expires", @"If-Match" , @"If-Modified-Since" , @"If-None-Match" , @"If-Unmodified-Since" , @"Origin" , @"Range" , @"transfer-encoding" ,@"Host",@"Pic-Operations",@"ci-process"];
// 注意 这里不要对 urlRequst 进行 copy 以及 mutableCopy 操作
QCloudSignature *signature = [creator signatureForData:urlRequst];
continueBlock(signature, nil);
}


@end
//AppDelegate.swift
//AppDelegate 需遵循 QCloudSignatureProvider
class AppDelegate: UIResponder, UIApplicationDelegate,
QCloudSignatureProvider {

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = QCloudServiceConfiguration.init();
let endpoint = QCloudCOSXMLEndPoint.init();
endpoint.regionName = "COS_REGION";
endpoint.useHTTPS = true;
config.endpoint = endpoint;
// 设置密钥回调代理
config.signatureProvider = self;
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
with: config);
return true
}

// 密钥回调的代理方法
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
/**
* 此处获取密钥,如果使用永久密钥则忽略
* ...
*/
/**
* 此处既可以是临时密钥也可以是永久密钥
* 临时密钥获取见:https://cloud.tencent.com/document/product/436/14048
* 注意:永久密钥不可用于生产环境,仅可作为调试使用
*/
let credential = QCloudCredential.init();
// 密钥 SecretId
credential.secretID = "SECRETID";
// 密钥 SecretKey
credential.secretKey = "SECRETKEY";
// 密钥 Token(如果使用永久密钥不需要填入,如果使用临时密钥需要填入)
credential.token = "TOKEN";
// 强烈建议返回服务器时间作为签名的开始时间, 用来避免由于用户手机本地时间偏差过大导致的签名不正确(参数 startTime 和 expiredTime 单位为秒)
credential.startDate = Date.init(timeIntervalSince1970: TimeInterval(startTime)!) DateFormatter().date(from: "startTime");
credential.expirationDate = Date.init(timeIntervalSince1970: TimeInterval(expiredTime)!)
let creator = QCloudAuthentationV5Creator.init(credential: credential);
// 注意:这里不要对 urlRequst 进行 copy 以及 mutableCopy 操作
let signature = creator?.signature(forData: urlRequst);
continueBlock(signature,nil);
}
}

import SwiftUI
import QCloudCOSXML

@main
struct SwiftUIDemoApp: App {
init() {
// 在应用初始化时调用 SDK 配置
COSManager.shared.setupCOSSDK();
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}


// COSManager需遵循QCloudSignatureProvider
class COSManager: NSObject, QCloudSignatureProvider {
static let shared = COSManager()
private override init() {}
func setupCOSSDK() {
let config = QCloudServiceConfiguration.init();
let endpoint = QCloudCOSXMLEndPoint.init();
endpoint.regionName = "COS_REGION";
endpoint.useHTTPS = true;
config.endpoint = endpoint;
config.signatureProvider = self;
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: config);
}

// 密钥回调的代理方法
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
/**
* 此处获取密钥,如果使用永久密钥则忽略
* ...
*/
/**
* 此处既可以是临时密钥也可以是永久密钥
* 临时密钥获取见:https://cloud.tencent.com/document/product/436/14048
* 注意:永久密钥不可用于生产环境,仅可作为调试使用
*/
let credential = QCloudCredential.init();
// 密钥 SecretId
credential.secretID = "SECRETID";
// 密钥 SecretKey
credential.secretKey = "SECRETKEY";
// 密钥 Token(如果使用永久密钥不需要填入,如果使用临时密钥需要填入)
credential.token = "TOKEN";
// 强烈建议返回服务器时间作为签名的开始时间, 用来避免由于用户手机本地时间偏差过大导致的签名不正确(参数 startTime 和 expiredTime 单位为秒)
credential.startDate = Date.init(timeIntervalSince1970: TimeInterval(startTime)!) DateFormatter().date(from: "startTime");
credential.expirationDate = Date.init(timeIntervalSince1970: TimeInterval(expiredTime)!)
let creator = QCloudAuthentationV5Creator.init(credential: credential);
// 注意:这里不要对 urlRequst 进行 copy 以及 mutableCopy 操作
let signature = creator?.signature(forData: urlRequst);
continueBlock(signature,nil);
}
}
说明:
此外SDK还提供了栅栏机制(QCloudCredentailFenceQueue),所有获取签名的请求会等待签名完成后在执行,免去了自己管理异步过程。注意:栅栏机制仅针对密钥回调这种方式有效并且仅适用客户端管理密钥的情况。

栅栏机制的使用如下:
Objective-C
Swift
SwiftUI

// AppDelegate需遵循QCloudCredentailFenceQueueDelegate
@interface AppDelegate () <QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate>
// 控制栅栏机制的对象
@property (nonatomic, strong) QCloudCredentailFenceQueue *credentialFenceQueue;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication * )application
didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
// ... SDK 初始化相关的流程此处省略
self.credentialFenceQueue = [QCloudCredentailFenceQueue new];
// 设置栅栏机制的代理对象
self.credentialFenceQueue.delegate = self;
return YES;
}

// 密钥回调代理中需要使用栅栏对象获取签名
- (void)signatureWithFields:(QCloudSignatureFields *)fileds
request:(QCloudBizHTTPRequest *)request
urlRequest:(NSMutableURLRequest *)urlRequst
compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock {
[self.credentialFenceQueue performAction:^(QCloudAuthentationCreator *creator, NSError *error) {
if (error) {
continueBlock(nil, error);
} else {
QCloudSignature *signature = [creator signatureForData:urlRequst];
continueBlock(signature, nil);
}
}];
}

// 栅栏机制的回调代理中获取密钥
- (void)fenceQueue:(QCloudCredentailFenceQueue *)queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock {
[[[NSURLSession sharedSession]dataTaskWithURL:[NSURL URLWithString:@"http://******"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 从业务服务接口请求临时密钥。
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingTopLevelDictionaryAssumed error:nil];
NSDictionary * credentials = dic[@"credentials"];
QCloudCredential *credential = [QCloudCredential new];
credential.secretID = credentials[@"tmpSecretId"];
credential.secretKey = credentials[@"tmpSecretKey"];;
credential.token = credentials[@"sessionToken"];;
//签名过期时间
credential.expirationDate = nil;
credential.startDate = nil;
QCloudAuthentationV5Creator *creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:credential];
continueBlock(creator, nil);
}] resume];
}

@end

import UIKit
import QCloudCOSXML

@main
class AppDelegate: UIResponder, UIApplicationDelegate, QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate {

var window: UIWindow?
var credentialFenceQueue: QCloudCredentailFenceQueue!
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ... SDK 初始化相关的流程此处省略
credentialFenceQueue = QCloudCredentailFenceQueue()
credentialFenceQueue.delegate = self
return true
}
// MARK: - QCloudSignatureProvider
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
credentialFenceQueue.performAction { (creator: QCloudAuthentationCreator?, error: Error?) in
if let error = error {
continueBlock(nil, error)
} else if let creator = creator {
let signature = creator.signature(for: urlRequst)
continueBlock(signature, nil)
}
}
}

// MARK: - QCloudCredentailFenceQueueDelegate
func fenceQueue(_ queue: QCloudCredentailFenceQueue!, requestCreatorWithContinue continueBlock: QCloudCredentailFenceQueueContinue!) {
// 构建请求临时密钥的 URL (请替换为您实际的服务器地址)
guard let url = URL(string: "http://******") else {
// 处理 URL 构造失败
let error = NSError(domain: "AppDelegate", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL for temporary key"])
continueBlock(nil, error)
return
}
let task = URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
// 处理网络错误
if let error = error {
continueBlock(nil, error)
return
}
// 确保数据存在
guard let data = data else {
let error = NSError(domain: "AppDelegate", code: -2, userInfo: [NSLocalizedDescriptionKey: "No data received from server"])
continueBlock(nil, error)
return
}
do {
// 解析 JSON 数据
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let credentials = json["credentials"] as? [String: Any],
let tmpSecretId = credentials["tmpSecretId"] as? String,
let tmpSecretKey = credentials["tmpSecretKey"] as? String,
let sessionToken = credentials["sessionToken"] as? String {
// 创建 QCloudCredential 对象并设置临时密钥
let credential = QCloudCredential()
credential.secretID = tmpSecretId
credential.secretKey = tmpSecretKey
credential.token = sessionToken
// 如果服务器返回了 startTime 和 expiredTime,建议设置
// credential.startDate = Date(timeIntervalSince1970: startTime)
// credential.expirationDate = Date(timeIntervalSince1970: expiredTime)
let creator = QCloudAuthentationV5Creator(credential: credential)
continueBlock(creator, nil)
} else {
// JSON 解析失败或键值缺失
let error = NSError(domain: "AppDelegate", code: -3, userInfo: [NSLocalizedDescriptionKey: "Failed to parse temporary key response"])
continueBlock(nil, error)
}
} catch {
// JSON 解析异常
continueBlock(nil, error)
}
}
task.resume() // 启动网络任务
}
}


import SwiftUI
import QCloudCOSXML

@main
struct SwiftUIDemoApp: App {
init() {
// 在应用初始化时调用 SDK 配置
COSManager.shared.setupCOSSDK();
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

class COSManager: NSObject, QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate
{
static let shared = COSManager()
private let credentialFenceQueue = QCloudCredentailFenceQueue()
private override init() {}
func setupCOSSDK() {
// ... SDK 初始化相关的流程此处省略
credentialFenceQueue.delegate = self
}
// MARK: - QCloudSignatureProvider
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
credentialFenceQueue.performAction { (creator: QCloudAuthentationCreator?, error: Error?) in
if let error = error {
continueBlock(nil, error)
} else if let creator = creator {
let signature = creator.signature(for: urlRequst)
continueBlock(signature, nil)
}
}
}


// MARK: - QCloudCredentailFenceQueueDelegate
func fenceQueue(_ queue: QCloudCredentailFenceQueue!, requestCreatorWithContinue continueBlock: QCloudCredentailFenceQueueContinue!) {
// 构建请求临时密钥的 URL (请替换为您实际的服务器地址)
guard let url = URL(string: "http://******") else {
// 处理 URL 构造失败
let error = NSError(domain: "AppDelegate", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL for temporary key"])
continueBlock(nil, error)
return
}
let task = URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
// 处理网络错误
if let error = error {
continueBlock(nil, error)
return
}
// 确保数据存在
guard let data = data else {
let error = NSError(domain: "AppDelegate", code: -2, userInfo: [NSLocalizedDescriptionKey: "No data received from server"])
continueBlock(nil, error)
return
}
do {
// 解析 JSON 数据
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let credentials = json["credentials"] as? [String: Any],
let tmpSecretId = credentials["tmpSecretId"] as? String,
let tmpSecretKey = credentials["tmpSecretKey"] as? String,
let sessionToken = credentials["sessionToken"] as? String {
// 创建 QCloudCredential 对象并设置临时密钥
let credential = QCloudCredential()
credential.secretID = tmpSecretId
credential.secretKey = tmpSecretKey
credential.token = sessionToken
// 如果服务器返回了 startTime 和 expiredTime,建议设置
// credential.startDate = Date(timeIntervalSince1970: startTime)
// credential.expirationDate = Date(timeIntervalSince1970: expiredTime)
let creator = QCloudAuthentationV5Creator(credential: credential)
continueBlock(creator, nil)
} else {
// JSON 解析失败或键值缺失
let error = NSError(domain: "AppDelegate", code: -3, userInfo: [NSLocalizedDescriptionKey: "Failed to parse temporary key response"])
continueBlock(nil, error)
}
} catch {
// JSON 解析异常
continueBlock(nil, error)
}
}
task.resume() // 启动网络任务
}
}


Objective-C
Swift
SwiftUI
//AppDelegate.m
//AppDelegate 需遵循 QCloudSignatureProvider
@interface AppDelegate()<QCloudSignatureProvider>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication * )application
didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {

QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];

// 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
// COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = @"COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
configuration.endpoint = endpoint;
// 密钥提供者为自己
configuration.signatureProvider = self;
// 初始化 COS 服务示例
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
configuration];
return YES;
}

- (void)signatureWithFields:(QCloudSignatureFields*)fileds
request:(QCloudBizHTTPRequest*)request
urlRequest:(NSMutableURLRequest*)urlRequst
compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
{
// 签名过期时间
NSDate *expiration = [[[NSDateFormatter alloc] init]
dateFromString:@"expiredTime"];
QCloudSignature *signature = [[QCloudSignature alloc] initWithSignature:
@"后台计算好的签名" expiration:expiration];
signature.token = @"临时密钥Token";// 永久密钥不需要 Token
continueBlock(signature, nil);
}
@end
//AppDelegate.swift
//AppDelegate 需遵循 QCloudSignatureProvider

class AppDelegate: UIResponder, UIApplicationDelegate,
QCloudSignatureProvider {

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let config = QCloudServiceConfiguration.init();

let endpoint = QCloudCOSXMLEndPoint.init();

// 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
// COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = "COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
config.endpoint = endpoint;
// 密钥提供者为自己
config.signatureProvider = self;

// 初始化 COS 服务示例
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
with: config);
return true
}
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
// 签名过期时间
let expiration = DateFormatter().date(from: "expiredTime");
let signature = QCloudSignature.init(signature: "后台计算好的签名",
expiration: expiration);
signature.token = "临时密钥Token";// 永久密钥不需要 Token
continueBlock(signature,nil);
}
}

import SwiftUI
import QCloudCOSXML

@main
struct SwiftUIDemoApp: App {
init() {
// 在应用初始化时调用 SDK 配置
COSManager.shared.setupCOSSDK();
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

class COSManager: NSObject, QCloudSignatureProvider {
static let shared = COSManager()
private override init() {}
func setupCOSSDK() {
let config = QCloudServiceConfiguration.init();
let endpoint = QCloudCOSXMLEndPoint.init();
// 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
// COS 支持的所有 region 列表参见 https://www.qcloud.com/document/product/436/6224
endpoint.regionName = "COS_REGION";
// 使用 HTTPS
endpoint.useHTTPS = true;
config.endpoint = endpoint;
config.signatureProvider = self;
// 初始化 COS 服务示例
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(with: config);
}

// 获取签名的方法入口,这里演示了获取临时密钥并计算签名的过程
// 您也可以自定义计算签名的过程
func signature(with fileds: QCloudSignatureFields!,
request: QCloudBizHTTPRequest!,
urlRequest urlRequst: NSMutableURLRequest!,
compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
// 签名过期时间
let expiration = DateFormatter().date(from: "expiredTime");
let signature = QCloudSignature.init(signature: "后台计算好的签名",
expiration: expiration);
signature.token = "临时密钥Token";// 永久密钥不需要 Token
continueBlock(signature,nil);
}
}

配置域名

SDK 支持自定义域名访问 COS 的相关服务。
使用方式:在“初始化 COS 服务”步骤中,实例化 QCloudCOSXMLEndPoint 时传入指定的域名。
说明:
若业务方中不需要指定自定义源站域名或全球加速域名,则跳过该步骤。
业务方可以通过 域名管理概述全球加速概述了解自定义源站域名和全球加速域名。
建议使用自定义源站域名或全球加速域名,不推荐使用自定义 CDN 加速域名。CDN 加速域名主要用于加速下载,不适用于加速上传场景。若使用 CDN 加速域名,则没有加速效果。
Objective-C
Swift
NSString *customDomain = @"exampledomain.com"; // 自定义源站域名或全球加速域名
QCloudCOSXMLEndPoint *endpoint = [[QCloudCOSXMLEndPoint alloc] initWithLiteralURL:[NSURL URLWithString:customDomain]];
QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
// 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
// COS 支持的所有 region 列表参见https://www.qcloud.com/document/product/436/6224
// 使用 HTTPS
endpoint.regionName = @"COS_REGION";
endpoint.useHTTPS = true;
configuration.endpoint = endpoint;
// 初始化 COS 服务示例
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
configuration];
let endpoint = QCloudCOSXMLEndPoint.init(literalURL: NSURL.init(string: "exampledomain.com") as URL?);
let config = QCloudServiceConfiguration.init();
// 替换为用户的 region,已创建桶归属的 region 可以在控制台查看,https://console.cloud.tencent.com/cos5/bucket
// COS 支持的所有 region 列表参见https://www.qcloud.com/document/product/436/6224
// 使用 HTTPS
endpoint.useHTTPS = true;
endpoint.regionName = "COS_REGION";
config.endpoint = endpoint;

// 初始化 COS 服务示例
QCloudCOSXMLService.registerDefaultCOSXML(with: config);
QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
with: config);


配置并发(可选)

SDK 支持自定义请求并发数。
使用方式:在“初始化 COS 服务”步骤中,自定义并发数以及并发数自增上限。
说明:
SDK 内部请求为多线程并发请求,并发数默认1,并且根据实时网速进行自动增减,最小1,最大4。
Objective-C
Swift
// 设置并发数4
[QCloudHTTPSessionManager shareClient].customConcurrentCount = 4;
// 设置自动上限8
[QCloudHTTPSessionManager shareClient].maxConcurrencyTask = 8;
// 设置并发数4
QCloudHTTPSessionManager.shareClient.customConcurrentCount = 4;
// 设置自动上限8
QCloudHTTPSessionManager.shareClient.maxConcurrencyTask = 8;

访问 COS 服务

以文件上传/下载为例介绍如何访问 SDK 的相关服务。
文件上传
文件下载
SDK 支持上传本地文件与二进制数据 NSData。下面以上传本地文件为例。
Objective-C
Swift
QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
// 本地文件路径
NSURL* url = [NSURL fileURLWithPath:@"文件的URL"];
// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
put.bucket = @"examplebucket-1250000000";
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = @"exampleobject";
//需要上传的对象内容。可以传入 NSData* 或者 NSURL* 类型的变量
put.body = url;
//监听上传进度
[put setSendProcessBlock:^(int64_t bytesSent,
int64_t totalBytesSent,
int64_t totalBytesExpectedToSend) {
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
}];

//监听上传结果
[put setFinishBlock:^(id outputObject, NSError *error) {
//可以从 outputObject 中获取 response 中 etag 或者自定义头部等信息
NSDictionary * result = (NSDictionary *)outputObject;
}];

[[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
let put:QCloudCOSXMLUploadObjectRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>();
// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
put.bucket = "examplebucket-1250000000";
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = "exampleobject";
//需要上传的对象内容。可以传入 NSData* 或者 NSURL* 类型的变量
put.body = NSURL.fileURL(withPath: "Local File Path") as AnyObject;

//监听上传结果
put.setFinish { (result, error) in
// 获取上传结果
if error != nil{
print(error!);
}else{
print(result!);
}
}

//监听上传进度
put.sendProcessBlock = { (bytesSent, totalBytesSent,
totalBytesExpectedToSend) in
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
};
//设置上传参数
put.initMultipleUploadFinishBlock = {(multipleUploadInitResult, resumeData) in
//在初始化分块上传完成以后会回调该 block,在这里可以获取 resumeData
//并且可以通过 resumeData 生成一个分块上传的请求
let resumeUploadRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>
.init(request: resumeData as Data?);
}

QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(put);

Objective-C
Swift
QCloudCOSXMLDownloadObjectRequest * request = [QCloudCOSXMLDownloadObjectRequest new];

// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
request.bucket = @"examplebucket-1250000000";
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
request.object = @"exampleobject";

//设置下载的路径 URL,如果设置了,文件将会被下载到指定路径中
request.downloadingURL = [NSURL fileURLWithPath:@"Local File Path"];

//监听下载结果
[request setFinishBlock:^(id outputObject, NSError *error) {
//outputObject 包含所有的响应 http 头部
NSDictionary* info = (NSDictionary *) outputObject;
}];

//监听下载进度
[request setDownProcessBlock:^(int64_t bytesDownload,
int64_t totalBytesDownload,
int64_t totalBytesExpectedToDownload) {
// bytesDownload 本次要下载的字节数(一个大文件可能要分多次发送)
// totalBytesDownload 已下载的字节数
// totalBytesExpectedToDownload 本次要下载的总字节数(即一个文件大小)
}];

[[QCloudCOSTransferMangerService defaultCOSTransferManager] DownloadObject:request];
let request : QCloudCOSXMLDownloadObjectRequest = QCloudCOSXMLDownloadObjectRequest();

// 存储桶名称,由 BucketName-Appid 组成,可以在 COS 控制台查看 https://console.cloud.tencent.com/cos5/bucket
request.bucket = "examplebucket-1250000000";
// 对象键
request.object = "exampleobject";

//设置下载的路径 URL,如果设置了,文件将会被下载到指定路径中
request.downloadingURL = NSURL.fileURL(withPath: "Local File Path") as URL?;

//监听下载进度
request.downProcessBlock = { (bytesDownload, totalBytesDownload,
totalBytesExpectedToDownload) in
// bytesDownload 本次要下载的字节数(一个大文件可能要分多次发送)
// totalBytesDownload 已下载的字节数
// totalBytesExpectedToDownload 本次要下载的总字节数(即一个文件大小)
}

//监听下载结果
request.finishBlock = { (copyResult, error) in
if error != nil{
print(error!);
}else{
print(copyResult!);
}
}

QCloudCOSTransferMangerService.defaultCOSTransferManager().downloadObject(request);

说明:
更多完整示例,请前往 GitHub 查看。
上传之后,您可以用同样的 Key 生成文件下载链接,具体使用方法请参见 生成预签名链接 文档。但注意如果您的文件是私有读权限,那么下载链接只有一定的有效期。

常见问题

如果您在使用 XML 版本 SDK 时遇到函数或方法不存在等错误,请先将 XML 版本 SDK 升级到最新版再重试。如果您仍在使用 JSON 版本 SDK,请 升级到 XML iOS SDK