开发者社区> 问答> 正文

阿里云osssdkforios

做过太多网站了,当然,都是传统的。虽然跟阿里云结缘有两年多了,但一直都拿ecs做普通服务器用,真正所谓的云服务,基本没涉及过,哎,菜鸟啊……
新的项目用到了oss,我相信很多人都会很纳闷,阿里云官方是没有提供oss-for-IOS的SDK的。而我本人之前也没有接触过IOS开发,一时各种蛋疼,各种研究!
总算有些眉目了,由于是IOS 0基础的人,就不卖弄来写什么封装好的sdk了,只提供个思路,各路大侠该骂使劲骂……


MD,废话太多了,入主题:
基于AFN来做的话,只需要做好request的header管理就OK。语文不行,尼玛,不知道怎么写,上代码:
#import <CommonCrypto/CommonHMAC.h>
/**
* 获取 authorization 所要求的 HMACSHA1
* @param string 按照OSS文档将HTTPHeaders拼接出来的字符串
* @param key ALIYUN_ACCESS_KEY
* @return NSData
*/
static NSData * AFHMACSHA1EncodedDataFromStringWithKey(NSString *string, NSString *key) {
    NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];
    CCHmacContext context;
    const char *keyCString = [key cStringUsingEncoding:NSASCIIStringEncoding];
    
    CCHmacInit(&context, kCCHmacAlgSHA1, keyCString, strlen(keyCString));
    CCHmacUpdate(&context, [data bytes], [data length]);
    
    unsigned char digestRaw[CC_SHA1_DIGEST_LENGTH];
    NSInteger digestLength = CC_SHA1_DIGEST_LENGTH;
    
    CCHmacFinal(&context, digestRaw);
    
    return [NSData dataWithBytes:digestRaw length:digestLength];
}

//FIXME: You Need to CHANGE the DateFormat for ALIYUN OSS
static NSString * AFRFC822FormatStringFromDate(NSDate *date) {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
    [dateFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss z"];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    
    return [dateFormatter stringFromDate:date];
}

static NSString * AFBase64EncodedStringFromData(NSData *data) {
    NSUInteger length = [data length];
    NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    
    uint8_t *input = (uint8_t *)[data bytes];
    uint8_t *output = (uint8_t *)[mutableData mutableBytes];
    
    for (NSUInteger i = 0; i < length; i += 3) {
        NSUInteger value = 0;
        for (NSUInteger j = i; j < (i + 3); j++) {
            value <<= 8;
            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }
        
        static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        
        NSUInteger idx = (i / 3) * 4;
        output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F];
        output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F];
        output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6)  & 0x3F] : '=';
        output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0)  & 0x3F] : '=';
    }
    
    return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding];
}

-(void )authorizationHeadersForRequest:(NSMutableURLRequest * __autoreleasing *)request {
    // Long header values that are subject to "folding" should split into new lines
    // according to Aliyun-OSS's documentation.
    NSAssert(_accessId && _accessKey, @"ALIYUN_ACCESS_ID && ALIYUN_ACCESS_KEY must not be nil");
    
    NSMutableDictionary *headerFields = [NSMutableDictionary dictionary];
    [[*request allHTTPHeaderFields] enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
        key = [key lowercaseString];
        if ([key hasPrefix:@"x-oss-"]) {
            if ([headerFields objectForKey:key]) {
                value = [[headerFields objectForKey:key] stringByAppendingFormat:@",%@", value];
            }
            [headerFields setObject:value forKey:key];
        }
    }];
    
    NSMutableString *headerString = [NSMutableString string];
    for (NSString *key in [[headerFields allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
        id value = [headerFields objectForKey:key];
        [headerString appendFormat:@"%@:%@\n", key, value];
    }
    
    NSString *canonicalizedResource = [NSString stringWithFormat:@"%@", *request.URL.path];
    NSString *method = [*request HTTPMethod];
    NSString *contentMD5 = [*request valueForHTTPHeaderField:@"Content-MD5"];
    NSString *contentType = [*request valueForHTTPHeaderField:@"Content-Type"];
    NSString *date = AFRFC822FormatStringFromDate([NSDate date]);
    date = (date) ? date : @"";
    [*request setValue:date forHTTPHeaderField:@"Date"];
    
    NSMutableString *mutableString = [NSMutableString string];
    [mutableString appendFormat:@"%@\n", (method) ? method : @""];
    [mutableString appendFormat:@"%@\n", (contentMD5) ? contentMD5 : @""];
    [mutableString appendFormat:@"%@\n", (contentType) ? contentType : @""];
    [mutableString appendFormat:@"%@\n", date];
    [mutableString appendFormat:@"%@", headerString];
    [mutableString appendFormat:@"%@", canonicalizedResource];
    
    NSData *hmac = AFHMACSHA1EncodedDataFromStringWithKey(mutableString, ALIYUN_ACCESS_KEY);
    NSString *signature = AFBase64EncodedStringFromData(hmac);
    NSString *authorization = [NSString stringWithFormat:@"OSS %@:%@", ALIYUN_ACCESS_ID, signature];
    
    [*request setValue:authorization forHTTPHeaderField:@"Authorization"];
    
}






展开
收起
plutodream 2014-09-10 14:33:10 13754 0
1 条回答
写回答
取消 提交回答
  • Re阿里云osssdkforios
    对了,在拼接请求域名的时候
    bucketname.oss-cn-region.aliyuncs.com貌似是不行的(不知道是不是我测试的问题)
    在我测试的时候,只能使用如下格式的域名
    oss-cn-region.aliyuncs.com/bucketname
    2014-09-10 14:38:48
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
计算巢软件免费试用中心,助力客户快速试用云上应用 立即下载
《云市场-云·企业官网产品介绍》 立即下载
阿里云产品九月刊 立即下载