Getting Started

Last updated: 2021-08-18 10:57:34

    Resources

    Note:

    If you encounter errors such as non-existent functions or methods when using the XML version of the SDK, please update the SDK to the latest version and try again.

    Preparations

    1. Prepare an iOS application; this can be an existing project or a new empty project.
    2. Make sure that the application is built using an SDK running on iOS 8.0 or above.
    3. You need a remote address where users can obtain your Tencent Cloud temporary key. For more information on temporary keys, see Practice of Direct Upload for Mobile Apps.

    Step 1. Install the SDK

    Method 1. Integration using CocoaPods (recommended)

    Standard SDK

    Add the following content to the Podfile of your project:

    pod 'QCloudCOSXML'
    

    Simplified SDK

    If you only need to perform upload and download operations and want a smaller sized SDK, you can use the simplified version.

    The simplified SDK is implemented through the CocoaPods subspec feature, so it currently can only be integrated automatically. Add the following content to the Podfile of your project:

    pod 'QCloudCOSXML/Transfer'
    

    Method 2. Manual integration

    You can directly download the latest version of the SDK here or you can find all of the versions here.

    1. Import binary libraries

    Drag QCloudCOSXML.framework, QCloudCore.framework, BeaconAPI_Base.framework, and BeaconId.framework into the project.

    Then, add the following dependent libraries:

    • CoreTelephony
    • Foundation
    • SystemConfiguration
    • libc++.tbd

    2. Configure your project

    Configure "Other Linker Flags" in "Build Settings" by adding this parameter:

    -ObjC
    -all_load
    

    Note:

    The SDK provides a packaging script that supports self-packaging according to business requirements. (The packaging script depends on CocoaPods. Please make sure CocoaPods is installed in your development environment first.) The packaging procedure is as follows:

    1. Download the source code: git clone https://github.com/tencentyun/qcloud-sdk-ios.
    2. Run the packaging script: source package.sh.
    3. Drag and drop the packaging result to the project and perform manual integration as described above.
      • iOS: drag and drop the packaging result in the ios folder to the project.
      • macOS: drag and drop the packaging result in the osx folder to the project.

    Step 2. Begin Using the SDK

    1. Import the header file

    Objective-c

    #import <QCloudCOSXML/QCloudCOSXML.h>
    

    swift

    import QCloudCOSXML
    

    For the simplified SDK, import the following:

    Objective-c

    #import <QCloudCOSXML/QCloudCOSXMLTransfer.h>
    

    swift

    import QCloudCOSXMLTransfer
    

    2. Initialize the COS service and implement the signature protocol

    Method 1. Obtaining a temporary key pair to authenticate requests (recommended)

    The SDK needs to get a temporary key to calculate the signature before sending a request. Therefore, you need to implement the 'QCloudSignatureProvider' protocol to obtain the key and call back the key to the SDK through the 'continueBlock' parameter.

    It is recommended to place the initialization process in 'AppDelegate' or application singleton.

    For the detailed procedure, see the following sample code:

    Objective-c

    // AppDelegate.m
    // `AppDelegate` must follow `QCloudSignatureProvider` 
    @interface AppDelegate()<QCloudSignatureProvider>
    @end
    @implementation AppDelegate
    - (BOOL)application:(UIApplication * )application 
        didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
      QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
    QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
    // Service region abbreviation; for example, `ap-guangzhou` is the abbreviation for the Guangzhou region
    endpoint.regionName = @"COS_REGION";
    // Use HTTPS
    endpoint.useHTTPS = true;
    configuration.endpoint = endpoint;
    // You are the key provider
    configuration.signatureProvider = self;
    // Initialize the COS instances
    [QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
    [QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
        configuration];
    return YES;
    }
    // Getting the signature: Here you can see how to get the temporary key and calculate the signature
    // You can also customize the signature calculation process
    - (void) signatureWithFields:(QCloudSignatureFields*)fileds
                     request:(QCloudBizHTTPRequest*)request
                  urlRequest:(NSMutableURLRequest*)urlRequst
                   compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
    {
        // Here, get the temporary key from the background server synchronously. It is highly recommended that the logic for getting a temporary key be placed here to maximize the availability of the key
    //...
    QCloudCredential* credential = [QCloudCredential new];
    // Temporary key SecretId
    credential.secretID = @"SECRETID";
    // Temporary key SecretKey
    credential.secretKey = @"SECRETKEY";
    // Temporary key token
    credential.token = @"TOKEN";
    /** You are advised to use the returned server time as the start time of the signature, to avoid signature errors caused by the large deviation between your phone’s local time and the system time (the unit of “startTime” and “expiredTime” is second).
    */
    credential.startDate = [NSDate dateWithTimeIntervalSince1970:startTime]; // Unit: second
    credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:expiredTime]]; // Unit: second
        QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
        initWithCredential:credential];
    QCloudSignature *signature = [creator signatureForData:urlRequst];
    continueBlock(signature, nil);
    }
    @end
    

    Swift

    //AppDelegate.swift
    // `AppDelegate` must follow `QCloudSignatureProvider` 
    class AppDelegate: UIResponder, UIApplicationDelegate,
    QCloudSignatureProvider {
      func application(_ application: UIApplication, 
        didFinishLaunchingWithOptions launchOptions: 
        [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let config = QCloudServiceConfiguration.init();
          let endpoint = QCloudCOSXMLEndPoint.init();
        // Service region abbreviation; for example, `ap-guangzhou` is the abbreviation for the Guangzhou region
        endpoint.regionName = "COS_REGION";
        // Use HTTPS
        endpoint.useHTTPS = true;
        config.endpoint = endpoint;
        // You are the key provider
        config.signatureProvider = self;
          // Initialize the COS instances
        QCloudCOSXMLService.registerDefaultCOSXML(with: config);
        QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
            with: config);
        return true
    }
        // Getting the signature: Here you can see how to get the temporary key and calculate the signature
    // You can also customize the signature calculation process
    func signature(with fileds: QCloudSignatureFields!, 
        request: QCloudBizHTTPRequest!, 
        urlRequest urlRequst: NSMutableURLRequest!, 
        compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
    
                // Get the temporary key from the backend server synchronously
        //...
          let credential = QCloudCredential.init();
        // Temporary key SecretId
        credential.secretID = "SECRETID";
        // Temporary key SecretKey
        credential.secretKey = "SECRETKEY";
        // Temporary key token
        credential.token = "TOKEN";
        /** You are advised to use the returned server time as the start time of the signature, to avoid signature errors caused by the large deviation between your phone’s local time and the system time (the unit of “startTime” and “expiredTime” is second).
        */
        credential.startDate = Date.init(timeIntervalSince1970: TimeInterval(startTime)!) DateFormatter().date(from: "startTime");
        credential.expirationDate = Date.init(timeIntervalSince1970: TimeInterval(expiredTime)!) 
          let creator = QCloudAuthentationV5Creator.init(credential: credential);
        let signature = creator?.signature(forData: urlRequst);
        continueBlock(signature,nil);
    
    }
    }
    

    The SDK provides the QCloudCredentailFenceQueue scaffolding tool for you to cache and reuse your temporary key. After a key expires, the scaffolding tool will call the protocol again to retrieve the new key until the key expiration time is later than the current device time.

    Note:

    The scaffolding tool determines whether a key can be reused based only on whether the key expiration time is later than the current device time. If you set up a complex policy when requesting a key, the scaffolding tool is not recommended.

    It is recommended to place the initialization process in 'AppDelegate' or application singleton. You need to implement the following two protocols to use the scaffolding tool:

    • QCloudSignatureProvider
    • QCloudCredentailFenceQueueDelegate

    The following is the sample code:

    Objective-c

    // AppDelegate.m
    // `AppDelegate` needs to follow the `QCloudSignatureProvider` and 
    // `QCloudCredentailFenceQueueDelegate` protocols
    @interface AppDelegate()<QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate>
    // Scaffolding tool instance
    @property (nonatomic) QCloudCredentailFenceQueue* credentialFenceQueue;
    @end
    @implementation AppDelegate
    - (BOOL)application:(UIApplication * )application 
        didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {
    QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
    QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
    // Service region abbreviation; for example, `ap-guangzhou` is the abbreviation for the Guangzhou region
    endpoint.regionName = @"COS_REGION";
    // Use HTTPS
    endpoint.useHTTPS = true;
    configuration.endpoint = endpoint;
    // You are the key provider
    configuration.signatureProvider = self;
    // Initialize the COS instances
    [QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
    [QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
        configuration];
      // Initialize the temporary key scaffolding tool
    self.credentialFenceQueue = [QCloudCredentailFenceQueue new];
    self.credentialFenceQueue.delegate = self;
      return YES;
    }
    - (void) fenceQueue:(QCloudCredentailFenceQueue * )queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock
    {
    // Here, get the temporary key from the background server synchronously. It is highly recommended that the logic for getting a temporary key be placed here to maximize the availability of the key
    //...
      QCloudCredential* credential = [QCloudCredential new];
    // Temporary key SecretId
    credential.secretID = @"SECRETID";
    // Temporary key SecretKey
    credential.secretKey = @"SECRETKEY";
    // Temporary key token
    credential.token = @"TOKEN";
    /** You are advised to use the returned server time as the start time of the signature, to avoid signature errors caused by the large deviation between your phone’s local time and the system time (the unit of “startTime” and “expiredTime” is second).
    */
    credential.startDate = [NSDate dateWithTimeIntervalSince1970:startTime]; // Unit: second
    credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:expiredTime]]; // Unit: second
      QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
        initWithCredential:credential];
    continueBlock(creator, nil);
    }
    // Getting the signature: Here you can see how to get the temporary key and calculate the signature
    // You can also customize the signature calculation process
    - (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);
        }
    }];
    }
    @end
    

    Swift

    //AppDelegate.swift
    // `AppDelegate` needs to follow the `QCloudSignatureProvider` and 
    // `QCloudCredentailFenceQueueDelegate` protocols
    class AppDelegate: UIResponder, UIApplicationDelegate,
    QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate {
      var credentialFenceQueue:QCloudCredentailFenceQueue?;
      func application(_ application: UIApplication, 
        didFinishLaunchingWithOptions launchOptions: 
        [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let config = QCloudServiceConfiguration.init();
          let endpoint = QCloudCOSXMLEndPoint.init();
        // Service region abbreviation; for example, `ap-guangzhou` is the abbreviation for the Guangzhou region
        endpoint.regionName = "COS_REGION";
        // Use HTTPS
        endpoint.useHTTPS = true;
        config.endpoint = endpoint;
        // You are the key provider
        config.signatureProvider = self;
          // Initialize the COS instances
        QCloudCOSXMLService.registerDefaultCOSXML(with: config);
        QCloudCOSTransferMangerService.registerDefaultCOSTransferManger(
            with: config);
          // Initialize the temporary key scaffolding tool
        self.credentialFenceQueue = QCloudCredentailFenceQueue.init();
        self.credentialFenceQueue?.delegate = self;
          return true
    }
      func fenceQueue(_ queue: QCloudCredentailFenceQueue!, 
        requestCreatorWithContinue continueBlock: 
        QCloudCredentailFenceQueueContinue!) {
        // Get the temporary key from the backend server synchronously
        //...
          let credential = QCloudCredential.init();
        // Temporary key SecretId
        credential.secretID = "SECRETID";
        // Temporary key SecretKey
        credential.secretKey = "SECRETKEY";
        // Temporary key token
        credential.token = "TOKEN";
        /** You are advised to use the returned server time as the start time of the signature, to avoid signature errors caused by the large deviation between your phone’s local time and the system time (the unit of “startTime” and “expiredTime” is second).
        */
        credential.startDate = Date.init(timeIntervalSince1970: TimeInterval(startTime)!) DateFormatter().date(from: "startTime");
        credential.expirationDate = Date.init(timeIntervalSince1970: TimeInterval(expiredTime)!) 
          let auth = QCloudAuthentationV5Creator.init(credential: credential);
        continueBlock(auth,nil);
    }
      // Getting the signature: Here you can see how to get the temporary key and calculate the signature
    // You can also customize the signature calculation process
    func signature(with fileds: QCloudSignatureFields!, 
        request: QCloudBizHTTPRequest!, 
        urlRequest urlRequst: NSMutableURLRequest!, 
        compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
        self.credentialFenceQueue?.performAction({ (creator, error) in
            if error != nil {
                continueBlock(nil,error!);
            }else{
                let signature = creator?.signature(forData: urlRequst);
                continueBlock(signature,nil);
            }
        })
    }
    }
    
    Note:

    • For more information on the abbreviations of the COS bucket regions, please see Regions and Access Endpoints.
    • We recommend requesting data over HTTPS. However, if you want to use HTTP protocol, you need to enable HTTP transfer for your application so that it can run on iOS 9.0 or above. For detailed directions, please see Apple's official documentation Preventing Insecure Network Connections.

    If your QCloudServiceConfiguration has changed, you can register a new instance by using the following method:

    + (QCloudCOSTransferMangerService*) registerCOSTransferMangerWithConfiguration:(QCloudServiceConfig
    

    Method 2. Using a permanent key for local debugging

    You can use your Tencent Cloud permanent key for local debugging during the development phase. Since this method exposes the key to leakage risks, please be sure to switch to the temporary key method before launching your application.

    When using a permanent key, you can choose not to implement the QCloudCredentailFenceQueueDelegate protocol.

    Objective-C

    - (void) signatureWithFields:(QCloudSignatureFields*)fileds
                     request:(QCloudBizHTTPRequest*)request
                  urlRequest:(NSMutableURLRequest*)urlRequst
                   compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
    {
    
    QCloudCredential* credential = [QCloudCredential new];
    // You can log in to the CAM console to view and manage SECRETID and SECRETKEY.
    credential.secretID = @"SECRETID"; // SecretId of the permanent key
    credential.secretKey = @"SECRETKEY"; // SecretKey of the permanent key
      // Use the permanent key to calculate the signature
    QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc] 
        initWithCredential:credential];
    QCloudSignature* signature = [creator signatureForData:urlRequst];
    continueBlock(signature, nil);
    }
    

    Swift

    func signature(with fileds: QCloudSignatureFields!, 
                request: QCloudBizHTTPRequest!, 
                urlRequest urlRequst: NSMutableURLRequest!, 
                compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
    let credential = QCloudCredential.init();
    // You can log in to the CAM console to view and manage SECRETID and SECRETKEY.
    credential.secretID = "SECRETID"; // SecretId of the permanent key
    credential.secretKey = "SECRETKEY"; // SecretKey of the permanent key
      // Use the permanent key to calculate the signature
    let auth = QCloudAuthentationV5Creator.init(credential: credential);
    let signature = auth?.signature(forData: urlRequst)
    continueBlock(signature,nil);
    }
    

    Method 3. Using a backend-calculated signature to authenticate requests

    When the signature is generated on the backend, you can choose not to implement the QCloudCredentailFenceQueueDelegate protocol

    Objective-C

    - (void) signatureWithFields:(QCloudSignatureFields*)fileds
                     request:(QCloudBizHTTPRequest*)request
                  urlRequest:(NSMutableURLRequest*)urlRequst
                   compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
    {
    // Signature expiration time
    NSDate *expiration = [[[NSDateFormatter alloc] init] 
                            dateFromString:@"expiredTime"];
    QCloudSignature *sign = [[QCloudSignature alloc] initWithSignature:
        @"Signature calculated on backend" expiration:expiration];
    continueBlock(signature, nil);
    }
    

    Swift

    func signature(with fileds: QCloudSignatureFields!, 
                request: QCloudBizHTTPRequest!, 
                urlRequest urlRequst: NSMutableURLRequest!, 
                compelete continueBlock: QCloudHTTPAuthentationContinueBlock!) {
    // Signature expiration time
    let expiration = DateFormatter().date(from: "expiredTime");
    let sign = QCloudSignature.init(signature: "signature calculated on backend", 
                expiration: expiration);
    continueBlock(signature,nil);
    }
    

    Step 3. Access COS

    Uploading an Object

    The SDK allows you to upload local files and binary data in NSData format. The following uses local file upload as an example:

    Objective-C

    QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
    // Local file path
    NSURL* url = [NSURL fileURLWithPath:@"file URL"];
    // Bucket name in the format of `BucketName-APPID`
    put.bucket = @"examplebucket-1250000000";
    // Object key, i.e., the full path of a COS object. If the object is in a directory, the format should be "video/xxx/movie.mp4"
    put.object = @"exampleobject";
    // Content of the object to be uploaded. You can pass in variables in `NSData*` or `NSURL*` format
    put.body =  url;
    // Monitor the upload progress
    [put setSendProcessBlock:^(int64_t bytesSent,
                            int64_t totalBytesSent,
                            int64_t totalBytesExpectedToSend) {
    //      bytesSent                 Number of bytes to send in this request (a large file may require multiple requests)
    //      totalBytesSent            Total number of bytes sent so far
    //      totalBytesExpectedToSend  Total number of bytes expected to send, i.e. the size of the file
    }];
    // Monitor the upload result
    [put setFinishBlock:^(id outputObject, NSError *error) {
    // outputObject contains information such as the ETag or custom headers in the response.
    NSDictionary * result = (NSDictionary *)outputObject;
    }];
    [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
    
    Note:

    • For the complete sample, go to GitHub.
    • You can generate a download URL for the uploaded file using the same key. For detailed directions, please see Generating a Pre-Signed Link. Please note that for private-read files, the download URL is only valid for a limited period of time.

    Swift

    let put:QCloudCOSXMLUploadObjectRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>();
    // Bucket name in the format of `BucketName-APPID`
    put.bucket = "examplebucket-1250000000";
    // Object key, i.e., the full path of a COS object. If the object is in a directory, the format should be "video/xxx/movie.mp4"
    put.object = "exampleobject";
    // Content of the object to be uploaded. You can pass in variables in `NSData*` or `NSURL*` format
    put.body = NSURL.fileURL(withPath: "Local File Path") as AnyObject;
    // Monitor the upload result
    put.setFinish { (result, error) in
    // Get the upload result
    if error != nil{
        print(error!);
    }else{
        print(result!);
    }
    }
    // Monitor the upload progress
    put.sendProcessBlock = { (bytesSent, totalBytesSent,
    totalBytesExpectedToSend) in
    //      bytesSent                 Number of bytes to send in this request (a large file may require multiple requests)
    //      totalBytesSent            Total number of bytes sent so far
    //      totalBytesExpectedToSend  Total number of bytes expected to send, i.e. the size of the file
    };
    // Set the upload parameters
    put.initMultipleUploadFinishBlock = {(multipleUploadInitResult, resumeData) in
    // This block will be called back after the Initiate Multipart Upload operation is complete so you can get resumeData
    // and can generate a multipart upload request using resumeData.
    let resumeUploadRequest = QCloudCOSXMLUploadObjectRequest<AnyObject>
        .init(request: resumeData as Data?);
    }
    QCloudCOSTransferMangerService.defaultCOSTransferManager().uploadObject(put);
    
    Note:

    • For the complete sample, go to GitHub.
    • You can generate a download URL for the uploaded file using the same key. For detailed directions, please see Generating a Pre-Signed Link. Please note that for private-read files, the download URL is only valid for a limited period of time.

    Downloading an object

    Objective-C

    QCloudCOSXMLDownloadObjectRequest * request = [QCloudCOSXMLDownloadObjectRequest new];
    
    // Bucket name in the format of `BucketName-APPID`
    request.bucket = @"examplebucket-1250000000";
    // Object key, i.e., the full path of a COS object. If the object is in a directory, the format should be "video/xxx/movie.mp4"
    request.object = @"exampleobject";
    // Set the download URL. Once set, the file will be downloaded to the specified path
    request.downloadingURL = [NSURL fileURLWithPath:@"Local File Path"];
    // Monitor the download result
    [request setFinishBlock:^(id outputObject, NSError *error) {
    // `outputObject` contains all HTTP response headers
    NSDictionary* info = (NSDictionary *) outputObject;
    }];
    // Monitor the download progress
    [request setDownProcessBlock:^(int64_t bytesDownload,
                                int64_t totalBytesDownload,
                                int64_t totalBytesExpectedToDownload) {
    //      bytesDownload                   Number of bytes to download in this request (a large file may require multiple requests)
    //      totalBytesDownload              Number of bytes downloaded so far
    //      totalBytesExpectedToDownload    Total number of bytes expected to download, i.e. the size of the file
    }];
    [[QCloudCOSTransferMangerService defaultCOSTransferManager] DownloadObject:request];
    
    Note:

    For the complete sample, please go to GitHub.

    Swift

    let request : QCloudCOSXMLDownloadObjectRequest = QCloudCOSXMLDownloadObjectRequest();
    
    // Bucket containing the file
    request.bucket = "examplebucket-1250000000";
    // Object key
    request.object = "exampleobject";
    // Set the download URL. Once set, the file will be downloaded to the specified path
    request.downloadingURL = NSURL.fileURL(withPath: "Local File Path") as URL?;
    // Monitor the download progress
    request.sendProcessBlock = { (bytesDownload, totalBytesDownload,
    totalBytesExpectedToDownload) in
    //      bytesDownload                   Number of bytes to download in this request (a large file may require multiple requests)
    //      totalBytesDownload              Number of bytes downloaded so far
    //      totalBytesExpectedToDownload    Total number of bytes expected to download, i.e. the size of the file
    }
    // Monitor the download result
    request.finishBlock = { (copyResult, error) in
    if error != nil{
        print(error!);
    }else{
        print(copyResult!);
    }
    }
    QCloudCOSTransferMangerService.defaultCOSTransferManager().downloadObject(request);
    
    Note:

    For the complete sample, please go to GitHub.