日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

iOS端直接調用

視覺智能開放平臺的API接口推薦使用SDK進行調用,推薦在服務端進行接入,在客戶端直接接入AccessKey ID和AccessKey Secret有泄露風險,可以使用STS授權用戶調用服務。

背景信息

在進行iOS調用之前,需要使用STS服務獲取臨時訪問憑證。阿里云STS(Security Token Service)是阿里云提供的一種臨時訪問權限管理服務。您可以通過STS服務給其他用戶頒發臨時訪問憑證,該用戶可使用臨時訪問憑證,在規定時間內調用視覺智能開放平臺的各項服務。臨時訪問憑證無需透露您的長期密鑰,保障您的賬戶更加安全。獲取臨時訪問憑證,請參見獲取角色的臨時身份憑證

說明

阿里云視覺智能開放平臺各類目視覺AI能力API接入、接口使用或問題咨詢等,請通過釘釘群(23109592)加入阿里云視覺智能開放平臺咨詢群聯系我們。

方案一:若文件在上海地域OSS

若您的文件存放在上海OSS中,可以參見請求簽名的方式進行調用,本文以銀行卡識別(RecognizeBankCard)為例,僅展示關鍵步驟及關鍵代碼,完整的示例可下載iOSDemo。如果您需要調用其他算法,請參見注釋并根據實際業務修改相應的代碼。

交互流程

image

前提條件

獲取STS臨時憑證:

  1. 授予權限:

    在獲取STS臨時憑證之前,調用者(RAM用戶和RAM角色)需要被授權有調用STS接口的權限。您可以通過設置RAM權限策略來實現這一點。相關的設置步驟和權限策略可參見使用STS臨時訪問憑證訪問OSS文檔。您需要根據實際需求配置更細粒度的授權策略,防止出現權限過大的風險。關于更細粒度的授權策略配置詳情,請參見視覺智能開放平臺自定義權限策略參考

    重要

    為后續步驟進行,調用者(RAM用戶和RAM角色)需要被授權AliyunSTSAssumeRoleAccess(調用STS服務AssumeRole接口的權限)、AliyunVIAPIFullAccess(這里為了下列示例,給出的是管理視覺智能API的權限,但是在實際工作中,強烈建議您根據實際需求配置更細粒度的授權策略,防止出現權限過大的風險。關于更細粒度的授權策略配置詳情,請參見視覺智能開放平臺自定義權限策略參考)。

  2. 調用AssumeRole接口:

    使用已授權的RAM用戶或RAM角色調用AssumeRole接口,并按照接口文檔填寫必要參數。查閱AssumeRole接口的官方文檔以了解詳細的接口說明和使用方法。

  3. 使用STS Token:

    調用AssumeRole接口成功后,您會收到一個包含AccessKeyIdAccessKeySecretSecurityToken的STS Token(如下代碼)。在實際調用其他阿里云服務的接口時,您需要將代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID><ALIBABA_CLOUD_ACCESS_KEY_SECRET><ALIBABA_CLOUD_SECURITY_TOKEN>替換為阿里云STS Token數據中獲取的臨時AccessKeyIdAccessKeySecretSecurityToken

{
  "RequestId": "429D9967-C809-5A30-B65E-9B742CF*****",
  "AssumedRoleUser": {
    "Arn": "acs:ram::175805416243****:role/STStokenTestRole/STSsessionName",
    "AssumedRoleId": "39779315882322****:STSsessionName"
  },
  "Credentials": {
    "SecurityToken": "exampleToken",
    "AccessKeyId": "STS.exampleAccessKeyID",
    "AccessKeySecret": "exampleAccessKeySecret",
    "Expiration": "2024-06-12T03:21:29Z"
  }
}

步驟一:配置基本參數

下面提供的代碼段是調用阿里云的"銀行卡識別"服務,在iOSDemo的Tool/CallApiClient.m文件中。需要將代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>替換為前提條件中獲取的阿里云STS Token數據的臨時AccessKeyId、AccessKeySecret、SecurityToken

/**
  <ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>需替換為STS Token數據中獲取的臨時AccessKeyId、AccessKeySecret、SecurityToken
  如果您是用的子賬號AccessKey,還需要為子賬號授予權限AliyunVIAPIFullAccess,請參考http://m.bestwisewords.com/document_detail/145025.html
 */
const NSString* ACCESS_KEY_ID = @"<ALIBABA_CLOUD_ACCESS_KEY_ID>";
const NSString* ACCESS_KEY_SECRET = @"<ALIBABA_CLOUD_ACCESS_KEY_SECRET>";
const NSString* SECURITY_TOKEN = @"<ALIBABA_CLOUD_SECURITY_TOKEN>";

步驟二:調用服務端接口并計算簽名

下面提供的代碼段是針對視覺智能開放平臺API的簽名和請求發送過程的實現。簽名是云服務常用的一種安全措施,用于確保發送到云服務的請求是未經篡改的,并且是由擁有相應憑證的合法用戶發起的。具體邏輯文檔請參見文檔請求簽名

以下是該代碼段的具體含義和步驟:

  1. 設置API請求參數:使用bodyDict字典存儲必要的請求參數,例如Action(API名稱)、ImageURL(圖片地址)等,并添加一些簽名所需系統參數,如Timestamp(當前時間戳)、SignatureNonce(唯一隨機值)。

  2. 生成簽名:

    • 對參數按照ASCII碼的順序進行排序(bodyToFormString:)。

    • 根據HTTP請求方法、資源路徑和查詢字符串創建簽名字符串。

    • 使用HMAC-SHA1算法對簽名字符串進行簽名,然后進行Base64編碼(hmacSha1:data:)。

  3. 構造請求URL:插入生成的簽名和其他查詢參數到URL中,形成最終的完整請求URL。

  4. 發送請求:

    • 創建一個HTTP POST請求(request:)。

    • 設置請求的相關屬性,如Content-Type

    • 使用NSURLSession將請求發送出去,并在請求完成后通過block回調處理響應結果或錯誤。

  5. 處理響應:

    • 請求成功,解析響應數據,并通過回調將結果傳遞回去。

    • 請求失敗,解析錯誤信息,并通過回調將錯誤傳遞回去。

代碼示例(單擊查看詳情)

/**
 * ========================================================================================================================
 * 以下代碼僅僅為了調用服務端接口計算簽名,其邏輯可參考文檔:http://m.bestwisewords.com/document_detail/144904.html
 * ========================================================================================================================
 */

+(NSString*)allKeysGotoSignatureWithDict:(NSMutableDictionary*)bodyDict endpoint:(NSString*)endpoint accessSecret:(NSString*)accessSecret httpMethod:(NSString*)httpMethod apiVersion:(NSString*)apiVersion{
    // 系統參數
    bodyDict[@"SignatureMethod"] = @"HMAC-SHA1";
    bodyDict[@"SignatureNonce"] = [self getNonce];
    bodyDict[@"SignatureVersion"] = @"1.0";
    bodyDict[@"Timestamp"] = [self getTimestamp];
    bodyDict[@"Format"] = @"JSON";
    // 業務API參數
    bodyDict[@"RegionId"] = @"cn-shanghai";
    bodyDict[@"Version"] = apiVersion;
    //key升序排序
    NSString *sortedQueryString = [self bodyToFormString:bodyDict];

    NSMutableString *stringToSign = [NSMutableString string];
    [stringToSign appendString:[NSString stringWithFormat:@"%@&",httpMethod]];
    [stringToSign appendString:[NSString stringWithFormat:@"%@&",[self urlEncode:@"/"]]];
    [stringToSign appendString:[self urlEncode:sortedQueryString]];
    //hmacsha1 加簽
    NSString *sign = [self hmacSha1:[NSString stringWithFormat:@"%@&",accessSecret] data:stringToSign];
    // 簽名最后也要做特殊URL編碼
    NSString *signature = [self urlEncode:sign];
    //最后結果
    NSString *finalUrl = [NSString stringWithFormat:@"https://%@/?Signature=%@&%@",endpoint,signature,sortedQueryString];
    NSLog(@"finalUrl:%@",finalUrl);
    return finalUrl;
}

+(NSString*)hmacSha1:(NSString*)key data:(NSString*)data{
    const char *cKey  = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding];
    //sha1
    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
                                          length:sizeof(cHMAC)];
    NSString *hash = [HMAC base64EncodedStringWithOptions:0];//將加密結果進行一次BASE64編碼。
    return hash;
}

+(NSString*)getNonce{
    NSTimeInterval timestamp = [[NSDate date]timeIntervalSince1970];
    NSString *string = [NSString stringWithFormat:@"%f%@",timestamp, [[NSUUID UUID]UUIDString]];
    NSString*md5 = [self md5String:string];
    return md5;
}

// md5
+ (NSString *)md5String:(NSString *)string{
    const char *cStr = [string UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
    return [NSString stringWithFormat:
                @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
    ];
}

+(NSString*)getTimestamp {
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
    formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'";
    return [formatter stringFromDate:[NSDate date]];
}

+(NSString*)bodyToFormString:(NSMutableDictionary*)query{
    NSString* url = @"";
    if (query != nil && query.count > 0) {
        NSArray *keys = query.allKeys;
        NSArray*sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2) {
            return[obj1 compare:obj2 options:NSNumericSearch];//正序排列
        }];
        NSMutableArray *arr = [NSMutableArray array];
        for (NSString *key in sortedArray) {
            NSString *value = query[key];
            if (value.length==0) {
                continue;
            }
            NSString *key2 = [NSString stringWithFormat:@"%@=%@",[self urlEncode:key],[self urlEncode:value]];
            [arr addObject:key2];
        }
        if(arr.count > 0) {
            url = [arr componentsJoinedByString:@"&"];
        }
    }
    return url;
}

+(NSString*)urlEncode:(NSString*)value{
    NSString *unreserved = @"*-._";
    NSMutableCharacterSet *allowedCharacterSet = [NSMutableCharacterSet alphanumericCharacterSet];
    [allowedCharacterSet addCharactersInString:unreserved];
    [allowedCharacterSet addCharactersInString:@" "];
    NSString *encoded = [value stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    encoded = [encoded stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
    encoded = [encoded stringByReplacingOccurrencesOfString:@"+" withString:@"%20"];
    encoded = [encoded stringByReplacingOccurrencesOfString:@"*" withString:@"%2A"];
    encoded = [encoded stringByReplacingOccurrencesOfString:@"%7E" withString:@"~"];
    return encoded ;
}

+(void)request:(NSString*)request responseBlock:(void(^)(NSDictionary *responseObject, NSError *error))block{
    NSMutableURLRequest *msRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:request]];
    [msRequest setHTTPMethod:@"POST"];
    msRequest.timeoutInterval = 60;
    [msRequest addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:msRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSError *parseError = nil;
        if(httpResponse.statusCode == 200){
            NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
            NSLog(@"response:%@",responseDictionary);
            block([responseDictionary objectForKey:@"Data"],nil);
        }else{
            NSLog(@"%@,error:%@",httpResponse,error);
            if (error) {
                block(nil,error);
            }else{
                NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                NSLog(@"errorDict:%@",errorDict);
                NSString *codevalue = [errorDict objectForKey:@"Code"];
                NSString *msgvalue = [errorDict objectForKey:@"Message"];
                NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"code:%@,error msg:%@",codevalue,msgvalue], NSLocalizedDescriptionKey,nil];
                parseError = [[NSError alloc] initWithDomain:NSCocoaErrorDomain code:httpResponse.statusCode userInfo:info];
                block(nil,parseError);
            }
        }
    }];
    [dataTask resume];
}

@end

步驟三:封裝請求并發送數據至指定視覺智能開放平臺API

下面提供的代碼段是如何在iOS應用中調用阿里云的RecognizeBankCard API來識別銀行卡信息。整個過程涉及到準備請求參數、生成請求簽名、構造請求URL,以及發起網絡請求和處理響應的步驟。

以下是該代碼段的具體含義和步驟:

  1. 準備請求參數:聲明一個NSMutableDictionary類型的字典bodyDict來存放請求需要的參數,包括:

    • AccessKeyId:訪問阿里云API需要的訪問密鑰。

    • Action:API的操作名稱,此處為RecognizeBankCard,表示調用阿里云的銀行卡識別服務。

    • ImageURL:需要識別的銀行卡圖片的URL。

    • SecurityToken:為了支持使用臨時訪問憑證而添加的參數,需要從Security Token Service(STS)獲取。

  2. 簽名請求:所有請求到阿里云服務的API需要進行簽名以保證請求的安全性。在這個示例中,allKeysGotoSignatureWithDict:endpoint:accessSecret:httpMethod:apiVersion:方法用于計算簽名并構造最終的請求URL。簽名過程中會用到如HTTP方法(POST)、API版本和EndPoint等信息。

  3. 構造請求URL:使用前述方法計算得到包含簽名的請求URLfinalUrl

  4. 發起POST請求:通過自定義request:responseBlock:方法使用NSURLSession發起一個POST請求到計算好的finalUrl。請求成功或失敗后,會通過回調block返回數據或錯誤信息給調用者。

  5. 異步處理響應:網絡請求和響應處理是異步的,確保不會阻塞主線程。回調block的執行被安排在主線程的dispatch隊列中,以便可以安全地更新UI或處理數據。

代碼示例(單擊查看詳情

/**
 以RecognizeBankCard為例。
 @param imageUrl 銀行卡圖片url
 */
+(void)recognizeBankCardWithImageUrl:(NSString*)imageUrl responseBlock:(void(^)(NSDictionary *data, NSError *error))block{
    NSMutableDictionary *bodyDict = [NSMutableDictionary dictionary];
    bodyDict[@"AccessKeyId"] = ACCESS_KEY_ID;
    // API Action,能力名稱,請參考具體算法文檔詳情頁中的Action參數,這里以銀行卡識別為例:http://m.bestwisewords.com/document_detail/151893.html
    bodyDict[@"Action"] = @"RecognizeBankCard";
    // 業務參數,請參考具體的AI能力的API文檔
    bodyDict[@"ImageURL"] = imageUrl;

    // 添加STS的SecurityToken
    bodyDict[@"SecurityToken"] = SECURITY_TOKEN;
    // 驗簽
    // 這里endpoint為API訪問域名,與類目相關,具體類目的API訪問域名請參考:http://m.bestwisewords.com/document_detail/143103.html
    // httpMethod推薦使用POST
    // apiVersion為API版本,與類目相關,具體類目的API版本請參考:http://m.bestwisewords.com/document_detail/464194.html
    NSString *finalUrl = [self allKeysGotoSignatureWithDict:bodyDict endpoint:@"ocr.cn-shanghai.aliyuncs.com" accessSecret:ACCESS_KEY_SECRET httpMethod:@"POST" apiVersion:@"2019-12-30"];
    //直接發post請求
    [self request:finalUrl responseBlock:^(NSDictionary *responseObject, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                block(nil,error);
            }else{
                block(responseObject, nil);
            }
        });
    }];
}

步驟四:頁面觸發按鈕并調用視覺智能開放平臺API

這段代碼展示了如何在iOS應用中調用封裝后的CallApiClient類中的recognizeBankCardWithImageUrl:responseBlock:方法來識別一張銀行卡圖片的信息。這是一個Objective-C的示例,用于展示從應用層面如何使用API客戶端。

  1. 設定圖片URL:

    • 定義變量imageUrl并將其設置為銀行卡圖片的URL地址。這張圖片存儲在阿里云的OSS上,并且是公開可訪問的。

  2. 調用API識別銀行卡:

    • 通過CallApiClient類的靜態方法recognizeBankCardWithImageUrl:responseBlock:調用銀行卡識別API,傳入圖片URL和一個回調block。這個回調block將在請求完成后執行,無論是成功還是失敗。

  3. 處理響應:

    • 在回調block中,首先檢查error對象來確定API調用是否成功。

      • 如果調用出現錯誤(error不為nil),則應該處理這個錯誤。錯誤處理可能包括日志記錄、顯示錯誤信息給用戶等。

      • 如果調用成功(errornil),則可以從回調傳回的data字典中提取銀行卡識別的結果。這里的例子演示了如何獲取銀行卡號(cardNumber)。實際上,根據API的文檔,您可能還可以獲取到其他有用的信息(如銀行名稱、卡類型等)。

  4. 顯示結果:

    • 在成功獲取銀行卡號后,示例中使用alertInfomation:方法(在這個示例中未實現,需要你自己定義)顯示一個提示框,將銀行卡號展示給用戶。這是一種簡單直接的反饋方式,適用于快速原型或測試應用。

說明

這段代碼整體上展示了從發起API請求到接收并處理API響應的完整流程。它對于理解如何在實際iOS應用中集成和使用外部API是一個有用的參考。需要注意的是,在一個完整的應用實現中,你可能還需要考慮更多的錯誤處理和異常場景。此外,出于用戶體驗的考慮,在請求發出期間,可能還需要添加加載指示器來告知用戶正在進行網絡操作。

代碼示例(單擊查看詳情)

/**
 * 調用API
 */
- (void)callApi {
    
    NSString* imageUrl = @"http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeBankCard/yhk1.jpg";
    [CallApiClient recognizeBankCardWithImageUrl:imageUrl responseBlock:^(NSDictionary * _Nonnull data, NSError * _Nonnull error) {
        if (error) {
            if ([error.localizedDescription containsString:@"InvalidAccessKeyId.NotFound"]) {
                [self alertInfomation:@"請求報錯,請檢查您代碼中的YOUR_ACCESS_KEY_ID和YOUR_ACCESS_KEY_SECRET是否已經修改正確。"];
            } else if([error.localizedDescription containsString:@"InvalidApi.NotPurchase"]) {
                [self alertInfomation:@"請求報錯,您的賬號未開通視覺智能開放平臺相應類目,請進行開通:http://m.bestwisewords.com/document_detail/465341.html"];
            } else if([error.localizedDescription containsString:@"Unauthorized"]) {
                [self alertInfomation:@"請求報錯,您的子賬號未授予AliyunVIAPIFullAccess權限,請參考http://m.bestwisewords.com/document_detail/145025.html"];
            } else if([error.localizedDescription containsString:@"InvalidAction.NotFound"]) {
                [self alertInfomation:@"請求報錯,請檢查您調用的API和類目是否匹配,API和類目的關系請參考:http://m.bestwisewords.com/document_detail/465341.html,和訪問的域名是否匹配,類目和域名的關系請參考:http://m.bestwisewords.com/document_detail/143103.html"];
            } else {
                [self alertInfomation:error.localizedDescription];
            }
        } else {
            // 獲取銀行卡號,這里只是示例,請根據文檔獲取自己想要的出參
            NSString* cardNumber = [data objectForKey:@"CardNumber"];
            [self alertInfomation:[NSString stringWithFormat:@"銀行卡號:%@", cardNumber]];
        }
    }];
}

方案二:若文件在本地或可訪問的URL

若您的文件存放在本地或可訪問的URL,請參見文件URL處理,顯式地將文件轉換成上海OSS鏈接,再按照若文件在上海地域OSS進行調用。本文以銀行卡識別(RecognizeBankCard)為例,僅展示關鍵步驟及關鍵代碼,完整的示例可下載iOSDemo。如果您調用其他算法,請參見注釋和實際業務修改相應代碼。

交互流程

image

前提條件

獲取STS臨時憑證:

  1. 授予權限:

    在獲取STS臨時憑證之前,調用者(RAM用戶和RAM角色)需要被授權有調用STS接口的權限。您可以通過設置RAM權限策略來實現這一點。相關的設置步驟可參見使用STS臨時訪問憑證訪問OSS文檔。您需要根據實際需求配置更細粒度的授權策略,防止出現權限過大的風險。關于更細粒度的授權策略配置詳情,請參見視覺智能開放平臺自定義權限策略參考

    重要

    為后續步驟進行,調用者(RAM用戶和RAM角色)需要被授權AliyunSTSAssumeRoleAccess(調用STS服務AssumeRole接口的權限)、RAM角色授予上傳OSS文件的權限、AliyunVIAPIFullAccess(這里為了下列實例,給出的是管理視覺智能API的權限,您需要根據實際需求配置更細粒度的授權策略,防止出現權限過大的風險。關于更細粒度的授權策略配置詳情,請參見視覺智能開放平臺自定義權限策略參考

  2. 調用AssumeRole接口:

    使用已授權的RAM用戶或RAM角色調用AssumeRole接口,并按照接口文檔填寫必要參數。查閱AssumeRole接口的官方文檔以了解詳細的接口說明和使用方法。

  3. 使用STS Token:

    調用AssumeRole接口成功后,您會收到一個包含AccessKeyId、AccessKeySecret和SecurityToken的STS Token(如下代碼)。在實際調用其他阿里云服務的接口時,您需要將代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>替換為阿里云STS Token數據中獲取的臨時AccessKeyId、AccessKeySecret、SecurityToken

{
  "RequestId": "429D9967-C809-5A30-B65E-9B742CF*****",
  "AssumedRoleUser": {
    "Arn": "acs:ram::175805416243****:role/STStokenTestRole/STSsessionName",
    "AssumedRoleId": "39779315882322****:STSsessionName"
  },
  "Credentials": {
    "SecurityToken": "exampleToken",
    "AccessKeyId": "STS.exampleAccessKeyID",
    "AccessKeySecret": "exampleAccessKeySecret",
    "Expiration": "2024-06-12T03:21:29Z"
  }
}

步驟一:配置基本參數

下面提供的代碼段是調用阿里云的"銀行卡識別"服務,在iOSDemo的Tool/CallApiClient.m文件中。需要將代碼中的<ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>替換為前提條件中獲取的阿里云STS Token數據的臨時AccessKeyId、AccessKeySecret、SecurityToken

說明

此處的臨時的AccessKeyId、AccessKeySecret、SecurityToken是為了避免暴露自己的AccessKeyId和AccessKeySecret在前端界面上。下面(步驟二)獲取的STS Token臨時訪問權限是為了將上傳文件到臨時OSS bucket,從而得到RL地址。

/**
  <ALIBABA_CLOUD_ACCESS_KEY_ID>、<ALIBABA_CLOUD_ACCESS_KEY_SECRET>、<ALIBABA_CLOUD_SECURITY_TOKEN>需替換為STS Token數據中獲取的臨時AccessKeyId、AccessKeySecret、SecurityToken
  如果您是用的子賬號AccessKey,還需要為子賬號授予權限AliyunVIAPIFullAccess,請參考http://m.bestwisewords.com/document_detail/145025.html
 */
const NSString* ACCESS_KEY_ID = @"YOUR_ACCESS_KEY_ID";
const NSString* ACCESS_KEY_SECRET = @"YOUR_ACCESS_KEY_SECRET";
const NSString* SECURITY_TOKEN = @"<ALIBABA_CLOUD_SECURITY_TOKEN>";

步驟二:調用GetOssStsToken接口獲取臨時OSS STS Token

下面提供的代碼段是利用阿里云的Access Key ID和Access Key Secret去請求一個臨時的阿里云OSS(對象存儲服務)STS(Security Token Service)令牌。這個STS令牌將允許用戶以阿里云視覺智能開放平臺官方OSS-Bucket為目標存儲介質,上傳文件或數據。為便于用戶調試接口,文件在OSS上的存儲有效期被設定為1天。

以下是該代碼段的具體含義和步驟:

  1. 準備請求數據:使用給定的accessKeyaccessSecret,構建一個請求字典bodyDict,該字典包括需要的操作Action,這里是"GetOssStsToken"

  2. 簽名和構建最終URL:根據提供的參數,包括API的端點(endpoint),HTTP請求方法(建議為POST),以及API的版本號(這里為"2020-04-01"),使用這些信息對請求進行簽名,并構建出最終的請求URL。

  3. 發送請求:通過一個POST請求,將準備好的簽名和數據發送到設定的API端點。

  4. 處理響應:通過異步方式處理服務端返回的響應。如果遇到錯誤,回調函數將傳遞錯誤信息;如果成功,回調函數將傳遞包含STS令牌數據的字典。

Tool/CallApiClient.m文件中recognizeBankCardWithImageUrl函數中的bodyDict[@"Action"]、endpoint、apiVersion參數及bodyDict[@"ImageURL"]這一行代表業務參數。

例如,您想使用通用分割能力,通過通用分割API文檔可知該能力屬于分割摳圖類目(imageseg20191230),能力名稱為SegmentCommonImage,您需要將endpoint改為imageseg.cn-shanghai.aliyuncs.com,bodyDict[@"Action"]改為SegmentCommonImage,apiVersion為2019-12-30不用修改,bodyDict[@"ImageURL"]參數名為ImageURL不用修改。獲取結果的時候,需要獲取ImageURL,其含義不是銀行卡號,而是分割后的圖片地址。

代碼示例(單擊查看詳情)

/**
 獲取oss sts token,使用阿里云視覺智能開放平臺官方OSS-Bucket作為臨時存儲,僅為方便用戶方便調試接口使用,文件存儲有效期為1天。
 */
+(void)getOssStsTokenWithAk:(NSString*)accessKey andSk:(NSString*)accessSecret responseBlock:(void(^)(NSDictionary *data, NSError *error))block {
    NSMutableDictionary *bodyDict = [NSMutableDictionary dictionary];
    bodyDict[@"AccessKeyId"] = accessKey;
    // 獲取阿里云視覺智能開放平臺官方OSS-Bucket的stsToken的Action固定為GetOssStsToken
    bodyDict[@"Action"] = @"GetOssStsToken";
    // 驗簽
    // 這里endpoint為API訪問域名,獲取阿里云視覺智能開放平臺官方OSS-Bucket的stsToken的域名固定為:viapiutils.cn-shanghai.aliyuncs.com
    // httpMethod推薦使用POST
    // apiVersion為API版本,獲取阿里云視覺智能開放平臺官方OSS-Bucket的stsToken的域名固定為:2020-04-01
    NSString *finalUrl = [self allKeysGotoSignatureWithDict:bodyDict endpoint:@"viapiutils.cn-shanghai.aliyuncs.com" accessSecret:accessSecret httpMethod:@"POST" apiVersion:@"2020-04-01"];
    //直接發post請求
    [self request:finalUrl responseBlock:^(NSDictionary *responseObject, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                block(nil,error);
            }else{
                block(responseObject, nil);
            }
        });
    }];
}

步驟三:使用臨時OSS STS Token將文件上傳到阿里云視覺智能開放平臺官方OSS Bucket

下面提供的代碼段是將一些圖像數據上傳到阿里云對象存儲服務(OSS)使用一個臨時的STS Token進行認證和授權的功能。

以下是該代碼段的具體含義和步驟:

  1. 通過CallApiClient獲取STS Token: 使用提供的Access Key ID (accessKeyId) 和Access Key Secret (accessKeySecret),以及一個可能已經存在的securityToken,來請求從CallApiClient獲取STS Token。

  2. 初始化OSS Client: 使用獲取到的臨時憑證信息,創建一個OSS客戶端(OSSClient)實例以進行后續的OSS操作。客戶端配置(OSSClientConfiguration)包括設置重試次數、請求超時和資源傳輸最長時間等。

  3. 設置上傳請求: 創建一個OSSPutObjectRequest對象以指定上傳文件的詳細信息。文件將被上傳到固定的Bucket("viapi-customer-temp"),而對象鍵(objectKey)則由Access Key ID和一個隨機UUID組成以確保唯一性。

  4. 執行上傳任務: 調用putObject:方法來實際上傳圖像數據,這個過程將會異步進行。

  5. 獲取上傳文件的URL: 成功上傳后,使用OSS客戶端預簽名URL功能(presignConstrainURLWithBucketName:withObjectKey:withExpirationInterval:)獲取上傳文件的訪問URL。

  6. 回調返回URL: 執行回調函數block,傳遞上傳文件的URL給調用者,或者在上傳失敗時返回錯誤信息。

說明

這一步需要在Frameworks中引入libresolv.tbd和AliyunOSSiOS.framework。其中,libresolv.tbd為系統庫,關于編譯和獲取AliyunOSSiOS.framework,請參見OSSiOS SDK安裝

代碼示例(單擊查看詳情)

#import "ViapiUtils.h"
#import "CallApiClient.h"
#import <AliyunOSSiOS/AliyunOSSiOS.h>

@implementation ViapiUtils

+(void)uploadWithAk:(NSString*)accessKeyId andSk:(NSString*)accessKeySecret andToken:(NSString*)securityToken  andData:(NSData *)imageData responseBlock:(void(^)(NSString *imageUrl, NSError *error))block {
    [CallApiClient getOssStsTokenWithAk:accessKeyId andSk:accessKeySecret andToken:securityToken responseBlock:^(NSDictionary * _Nonnull data, NSError * _Nonnull error) {
        if (error) {
            block(nil, error);
        } else {
            // 獲取到sts token,用來初始化oss client
            id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
                    OSSFederationToken * token = [OSSFederationToken new];
                    token.tAccessKey = [data objectForKey:@"AccessKeyId"];
                    token.tSecretKey =[data objectForKey:@"AccessKeySecret"];
                    token.tToken =[data objectForKey:@"SecurityToken"];
                    return token;
            }];
            OSSClientConfiguration *conf = [OSSClientConfiguration new];
            conf.maxRetryCount = 3; // 網絡請求遇到異常失敗后的重試次數
            conf.timeoutIntervalForRequest = 20; // 網絡請求的超時時間
            conf.timeoutIntervalForResource = 24*60*60; // 允許資源傳輸的最長時間
            conf.maxConcurrentRequestCount = 30;
            OSSClient *client = [[OSSClient alloc] initWithEndpoint:@"http://oss-cn-shanghai.aliyuncs.com" credentialProvider:credential clientConfiguration:conf];
            
            OSSPutObjectRequest * put = [OSSPutObjectRequest new];
            // bucketName固定填viapi-customer-temp
            put.bucketName = @"viapi-customer-temp";
            NSString *sourceNameObjectKey = [NSString stringWithFormat:@"%@/%@",accessKeyId,[[NSUUID UUID]UUIDString]];
            put.objectKey = sourceNameObjectKey;
            NSLog(@"put.objectKey:%@ [NSData dataWithContentsOfFile:file]==%@",put.objectKey,data);
            put.uploadingData = imageData;
            OSSTask * putTask = [client putObject:put];
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                [putTask continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
                    if (!task.error) {
                        OSSTask *downloadURLTask = [client presignConstrainURLWithBucketName:@"viapi-customer-temp" withObjectKey:put.objectKey withExpirationInterval:24*3600];
                        NSString * string = downloadURLTask.result;
                        NSLog(@"inner string:%@", string);
                        NSArray *arr =[string componentsSeparatedByString:@"?"];
                        NSString* imageUrl = arr.count > 0 ? arr[0] :string;
                        NSLog(@"upload object success! %@", imageUrl);
                        block(imageUrl, nil);
                    } else {
                        NSLog(@"upload object failed, error: %@" , putTask.error);
                        block(nil, putTask.error);
                    }
                    return nil;
                }];
                [putTask waitUntilFinished]; // 阻塞直到上傳完成
            });
        }
    }];
}

@end

步驟四:上傳之后得到OSS的URL地址,調用視覺智能開放平臺API

下面提供的代碼段用于上傳文件到OSS后獲取URL地址,調用視覺智能開放平臺API。具體的操作步驟與若文件在上海地域OSS進行調用一致。且每一步代碼都已封裝好,完整的示例代碼可下載iOSDemo

以下是該代碼段的具體含義和步驟:

  1. 參數設置:通過構建一個字典 bodyDict,設置所需的 API 參數。這包括:

    • AccessKeyIdAccessKeySecret:用于身份驗證的憑證。

    • SecurityToken:作為臨時安全憑證,通常與STS服務一起使用。

    • ImageURL:需要識別的銀行卡圖片的URL。

    • Action:指明要調用的API能力,這里是"RecognizeBankCard",即識別銀行卡。

  2. 準備API請求:

    • 代碼構建了一個簽名后的最終URLfinalUrl,該過程涵蓋了設置API的端點(endpoint)、推薦使用的POST方法、API的版本號,以及根據訪問密鑰、API端點和其他參數生成簽名的過程。

  3. 執行API請求:向構建好的 finalUrl 發送POST請求。這是通過 request:responseBlock: 方法實現的,該方法的具體實現尚未顯示,但可假定它負責將請求發送到服務器并處理響應。

  4. 響應處理:請求的響應通過異步回調 responseBlock 進行處理。如果請求成功,API的響應數據(識別出的銀行卡信息等)會通過 block(responseObject, nil) 返回給調用者。如果請求過程中出現錯誤,通過 block(nil, error) 將錯誤返回給調用者。

Tool/CallApiClient.m文件中recognizeBankCardWithImageUrl函數中的bodyDict[@"Action"]endpointapiVersion參數及bodyDict[@"ImageURL"]這一行代表業務參數。

例如,您想使用通用分割能力,通過通用分割API文檔可知該能力屬于分割摳圖類目(imageseg20191230),能力名稱為SegmentCommonImage,您需要將endpoint改為imageseg.cn-shanghai.aliyuncs.combodyDict[@"Action"]改為SegmentCommonImageapiVersion2019-12-30不用修改,bodyDict[@"ImageURL"]參數名為ImageURL不用修改。獲取結果的時候,需要獲取ImageURL,其含義不是銀行卡號,而是分割后的圖片地址。

代碼示例(單擊查看詳情)

+(void)recognizeBankCardWithImageUrl:(NSString*)imageUrl andAk:(NSString*)accessKey andSk:(NSString*)accessSecret andToken:(NSString*)securityToken  responseBlock:(void(^)(NSDictionary *data, NSError *error))block{
    NSMutableDictionary *bodyDict = [NSMutableDictionary dictionary];
    bodyDict[@"AccessKeyId"] = accessKey;
    // API Action,能力名稱,請參考具體算法文檔詳情頁中的Action參數,這里以銀行卡識別為例:http://m.bestwisewords.com/document_detail/151893.html
    bodyDict[@"Action"] = @"RecognizeBankCard";
    // 業務參數,請參考具體的AI能力的API文檔
    bodyDict[@"ImageURL"] = imageUrl;

    bodyDict[@"SecurityToken"] = securityToken;

    // 驗簽
    // 這里endpoint為API訪問域名,與類目相關,具體類目的API訪問域名請參考:http://m.bestwisewords.com/document_detail/143103.html
    // httpMethod推薦使用POST
    // apiVersion為API版本,與類目相關,具體類目的API版本請參考:http://m.bestwisewords.com/document_detail/464194.html
    NSString *finalUrl = [self allKeysGotoSignatureWithDict:bodyDict endpoint:@"ocr.cn-shanghai.aliyuncs.com" accessSecret:accessSecret httpMethod:@"POST" apiVersion:@"2019-12-30"];
    //直接發post請求
    [self request:finalUrl responseBlock:^(NSDictionary *responseObject, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                block(nil,error);
            }else{
                block(responseObject, nil);
            }
        });
    }];
}