美文网首页iOS 开发IT梦之队程序员
腾讯-----广点通iOS端接入实现

腾讯-----广点通iOS端接入实现

作者: 李逍遥_ | 来源:发表于2016-03-28 10:05 被阅读2352次
最近接到一个有关腾讯广告推广应用的渠道,需要实现,就是用到了广点通,而它的坑爹之处就在于,iOS版本的接入方式只有API,没有SDK,所以需要我们开发人员去逐字逐句理解然后实现调用他们服务端的接口,然而这个并不仅仅是一个接口调用那么简单;各种码的获取,各种加密方式,简直让人蛋碎,最主要的是人家TX的技术支持听说忙的不行,一般是不会理你的,API里面是Python语言写的什么异或的东西,居然让我一个写OC的自己搞定,所以经过这次蹚坑我决定把我的实现分享给大家,以便后来人乘凉😄--------

引入头文件

#import <CommonCrypto/CommonDigest.h>
#import <AdSupport/ASIdentifierManager.h>
#import "ZRGTMBase64.h" 
#import "RequestModel.h" //封装的数据请求类

定义基本的宏变量

//以下四个key是在创建一个转化成功之后生成的(详见文章最后备注)
#define gdt_encrypt_key @"xxxxxxxxxx"
#define gdt_sign_key    @"xxxxxxxxxx"
#define gdt_app_id      @"xxxxxxxxxx"
#define gdt_advertiser_id @"xxxxxxx"

#define adGetKey @"ZRAdDowlondCountObjectKey"
#define CC_MD5_DIGEST_LENGTH 16

用到的两个属性

@property (nonatomic,strong)RequestModel *requestModel;
@property (nonatomic,strong) NSMutableArray *adArray;

具体代码实现

//激活发送
- (void)send {
    
    _adArray = [NSMutableArray arrayWithArray:[self loadCustomObjectWithKey:adGetKey]];
    //只有第一次才发送
    if (_adArray.count && [[_adArray objectAtIndex:0] isEqualToString:@"1"]) {
        return;
    }
    
    if (!self.requestModel) {
        self.requestModel = [[RequestModel alloc] init];
    }
    
    __weak typeof(self) weakSelf = self;
    [self.requestModel loadDataeWithURlString:[self generateUrl] withResultBlock:^(NSDictionary *dict) {
        
        if ([[[dict objectForKey:@"ret"] stringValue] isEqualToString:@"0"]) {
            [_adArray removeAllObjects];
            //标记为已发送
            [_adArray addObject:@"1"];
            [weakSelf saveCustomObject:_adArray];
            
        }
        
    } withFailedBlock:^(NSError *error) {
        NSLog(@"发送失败:%@",error);
    }];
    
}

//生成url
-(NSString *)generateUrl {
    
    NSString *result = @"";
    
    NSString *encrypt_key = gdt_encrypt_key;
    NSString *sign_key = gdt_sign_key;
    NSString *app_id = gdt_app_id;
    NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    NSString *conv_type = @"MOBILEAPP_ACTIVITE";
    NSString *app_type = @"IOS";
    NSString *advertiser_id = gdt_advertiser_id;
    
    NSString *conv_time = [NSString stringWithFormat:@"%.0lf", [NSDate date].timeIntervalSince1970];
    
    NSString *muid = [self generateMuid:idfa];
    NSString *query_string = [NSString stringWithFormat:@"muid=%@&conv_time=%@", muid, conv_time];
    
    NSString *encode_page = [NSString stringWithFormat:@"http://t.gdt.qq.com/conv/app/%@/conv?%@", app_id, query_string];
    NSString *temp = [NSString stringWithFormat:@"%@&GET&%@", sign_key, [self encodeToPercentEscapeString:encode_page]];
    NSString *signature = [self getMd5_32Bit_String:temp];
    NSString* base_data = [query_string stringByAppendingFormat:@"&sign=%@", signature];
    
    NSString* v_data = [self encodeToPercentEscapeString:[ZRGTMBase64 stringByEncodingData:[self simpleXor:base_data key:encrypt_key]]];
    
    NSLog(@"query_string: %@", query_string);
    NSLog(@"v_data: %@", v_data);
    
    result = [NSString stringWithFormat:@"http://t.gdt.qq.com/conv/app/%@/conv?v=%@&conv_type=%@&app_type=%@&advertiser_id=%@", app_id, v_data, conv_type, app_type, advertiser_id];
    NSLog(@"\n%@", result);
    return result;
}

//生成muid
- (NSString *)generateMuid:(NSString *)idfa {
    idfa = [idfa uppercaseString];
    NSString* result = [self getMd5_32Bit_String:idfa];
    NSLog(@"muid--%@", result);
    return result;
}

//异或操作
- (NSData *)simpleXor:(NSString *)info key:(NSString *)key {
    
    const   char *infoBytes = [info UTF8String];
    const   char *keyBytes = [key UTF8String];
    
    int i = 0, j = 0;
    char *bytes = malloc(strlen(infoBytes));
    for (i = 0; i < strlen(infoBytes); i++) {
        bytes[i] = (char)(infoBytes[i]^keyBytes[j]);
        
        j++;
        j = j%(key.length);
    }
    
    //这一定要用strlen(infoBytes),不要用strlen(bytes),因为bytes里面有\0,而strlen只计算\0之前数,所以最终的长度偏小
    NSData *data = [NSData dataWithBytes:bytes length:strlen(infoBytes)];
    return data;
}

- (NSString *)getMd5_32Bit_String:(NSString *)srcString{
    const char *cstr = [srcString UTF8String];
    uint8_t digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cstr, (int)strlen(cstr), digest);
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02x",digest[i]];
    }
    return [result lowercaseString];
}
//urlEncode
- (NSString *)encodeToPercentEscapeString: (NSString *) input
{
    NSString *outputStr = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)input,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    return outputStr;
}


#pragma mark - 获取持久化数据 -----
- (void)saveCustomObject:(NSArray *)obj
{
    NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:myEncodedObject forKey:adGetKey];
    [defaults synchronize];
}

- (NSArray *)loadCustomObjectWithKey:(NSString *)key
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *myEncodedObject = [defaults objectForKey:key];
    NSArray *obj = (NSArray *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
    return obj;
}

备注:

TXLK(859Q%{4(2$K(467ED6.jpg

----最后,还是要感谢 gaoyuqiang30(CSDN)对我的支持指导-----

相关文章

网友评论

  • 微微一笑狠倾城_0e3e:楼主 有没有源码 可不可以发我一份啊 我的扣扣945227326 看到了 欢迎骚扰啊
    李逍遥_:这就是主要的代码,你自己建一个类放进去应该就OK了,我也是集成到工程里的,没有单独的
  • 豆志昂扬:提款成功过吗?
  • sosolove:有源码吗
    李逍遥_:这个就是主要的代码了,剩下的都是无关紧要的
  • 49c9990ff26c:前几天刚集成了,我在客户端仅仅是启动的时候发了一个IDFA码,剩下的后台记录就好吧...
    李逍遥_:恩,用方案二的话就这样就可以了

本文标题:腾讯-----广点通iOS端接入实现

本文链接:https://www.haomeiwen.com/subject/skejlttx.html