说在前面的话:iOS项目集成微信SDK,一般也就是登录,支付,分享等功能。下面就一些常遇到的坑和注意点做个记录,希望可以帮助到有需要的朋友~~
一.集成SDK
1.去微信开发者官网申请,下载SDK和Demo
2.按文档导入相应系统库
3.在info.plist设置URL Schemes和LSApplicationQueriesSchemes
这个过程会需要报一些错,不是缺少库就是path路径问题,Google之即可
之后就是AppDelegate.m里注册微信,下面重点介绍功能
二.登录
1. 第一步:网络请求https://api.weixin.qq.com/sns/oauth2/access_token?appid="申请的AppID"&secret="微信分配的key"&code="回调的code"&grant_type=authorization_code这个URL获取用户accessToken,openid
2.第二步:请求https://api.weixin.qq.com/sns/userinfo?access_token="第一步解析出的token"&openid="第一步解析的openid",解析JSON数据,获取用户的昵称,头像,性别等信息,根据实际情况是否存储,根据后台需求,获得的数据要怎么处理,AES加密或者Base64等等
3.第三步:与后台接口交互,把上述信息传给服务器,成功回调里发通知,跳转页面,改变根控制器等等一系列操作
(代码在最后贴)
三.支付
支付大体分2步,第一步设置支付的一些参数(包括sign签名),涉及到XML转义,比较坑,一般都是后台处理。(建议交给后台处理,因为涉及到加密)第二步就是设置商户号呀,签名呀,商品信息呀等等。
1需要注意的是,微信支付比例100:1,你传入的是1,吊起微信支付是0.01元。测试时期可以不改,上架前一定要处理!!!
2.需要传入用户IP,如果用户是用的流量,IP不是固定的,如果你用iOS自带的获取IP的方法传入IP值,就会吊起微信失败,坑吧?哈哈,建议写死了吧~对功能没有影响。其实最好的办法是判断网络环境,wifi就给个IP,流量的时候就给个死数据就行了
3.最好设计个管理登录、支付等一些操作的管理类,在这个类定义个block,微信支付成功之后,调用block,根据业务逻辑进行提示或页面跳转等
三.分享
分享没什么说的,上代码(所有的)
// 微信回调
if ([resp isKindOfClass:[SendAuthResp class]]) { // WeChat登陆成功
SendAuthResp *aresp = (SendAuthResp *)resp;
if (aresp.errCode == 0) {
NSString *code = aresp.code;
[self getAccess_tokenWithCode:code]; // 获取Access_token
}
} else if ([resp isKindOfClass:[PayResp class]]) { // WeChat支付成功
PayResp *response = (PayResp *)resp;
switch (response.errCode) {
case WXSuccess:
NSLog(@"支付成功");
if (self.payBack) {
self.payBack(YES);
}
break;
default:
NSLog(@"支付失败, retcode=%d", response.errCode);
if (self.payBack) {
self.payBack(NO);
}
break;
}
} else if ([resp isKindOfClass:[SendMessageToWXResp class]]) { // WeChat分享成功
SendMessageToWXResp * tmpResp = (SendMessageToWXResp *)resp;
if (tmpResp.errCode == WXSuccess) {
YYLog(@"微信分享成功");
}
}
-(void)getUserInfo {
NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@", [YYThirdPard sharedThirdPard].accessToken,[YYThirdPard sharedThirdPard].openid];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *zoneUrl = [NSURL URLWithString:url];
NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
if (!data) {
return;
}
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
[YYThirdPard sharedThirdPard].nickName = [dic objectForKey:@"nickname"];
[YYThirdPard sharedThirdPard].headImgURL = [dic objectForKey:@"headimgurl"];
[YYThirdPard sharedThirdPard].sex = [NSNumber numberWithInteger: ([[dic objectForKey:@"sex"] integerValue])];
[YYThirdPard sharedThirdPard].unionid = [dic objectForKey:@"unionid"];
YYLog(@"unionid === %@",[YYThirdPard sharedThirdPard].unionid);
NSMutableString *wxInfoStr = [NSMutableString stringWithString:[YYThirdPard sharedThirdPard].unionid];
[wxInfoStr appendString:@"|"];
[wxInfoStr appendString:[YYThirdPard sharedThirdPard].headImgURL];
[wxInfoStr appendString:@"|"];
[wxInfoStr appendString:[NSString stringWithFormat:@"%@",[YYThirdPard sharedThirdPard].sex]];
[wxInfoStr appendString:@"|"];
[wxInfoStr appendString:[YYThirdPard sharedThirdPard].nickName];
//加密
NSString *encrypt = [SecurityUtil encryptAESData:wxInfoStr.copy];
[self postWXInfo:encrypt];
});
});
}
#pragma mark - 微信登录后台绑定
- (void)postWXInfo:(NSString *)wx {
[[YYNetWorkTool sharedTool] WXLoginWithWXInfo:wx Finished:^(id response, NSError *error) {
if (error) {
NSLog(@"%@",error);
[SVProgressHUD setMinimumDismissTimeInterval:1.0];
[SVProgressHUD showErrorWithStatus:@"连接超时"];
return;
}
NSDictionary *dictGroup = (NSDictionary *)response;
NSDictionary *dictData = dictGroup[@"data"];
NSDictionary *dictAccount = dictData[@"account"];
YYUserInfo *userInfo = [YYUserInfo userInfoWithDict:dictAccount];
if (userInfo.token == nil) {
[SVProgressHUD dismiss];
return;
}
YYLog(@"%@",userInfo.token);
userInfo.nickname = [YYThirdPard sharedThirdPard].nickName;
userInfo.avatar = [YYThirdPard sharedThirdPard].headImgURL;
// 保存用户信息
[self saveUserAccount:userInfo];
_isUserWXLogin = YES;
// 登录成功,发个通知
[[NSNotificationCenter defaultCenter] postNotificationName:KWXLoginNotiKey object:nil];
}];
}
#pragma mark - 微信支付
- (void)WXPayWithPay_no:(NSString *)pay_no should_pay:(NSString *)should_pay attach:(NSString *)attach {
NSString *appid,*mch_id,*nonce_str,*sign,*body,*total_fee,*spbill_create_ip,*notify_url,*trade_type,*partner;
//应用APPID
appid = kWXAPP_ID;
//微信支付商户号
mch_id = KWXMCH_ID;
///产生随机字符串
nonce_str =[NSString randomString];
body = @"每家美物";
total_fee = should_pay;
//获取本机IP地址
// spbill_create_ip = [NSString getIPAddress];
spbill_create_ip = @"196.168.1.1";
//交易结果通知网站
notify_url = @"交易结果通知网站";
trade_type = @"APP";
//商户密钥
partner = KWXMCH_SECRET;
//附近数据
//获取sign签名
DataMD5 *data = [[DataMD5 alloc] initWithAppid:appid mch_id:mch_id nonce_str:nonce_str partner_id:partner body:body attach:attach out_trade_no:pay_no total_fee:total_fee spbill_create_ip:spbill_create_ip notify_url:notify_url trade_type:trade_type];
sign = [data getSignForMD5];
//设置参数并转化成xml格式
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setValue:appid forKey:@"appid"];//公众账号ID
[dic setValue:mch_id forKey:@"mch_id"];//商户号
[dic setValue:nonce_str forKey:@"nonce_str"];//随机字符串
[dic setValue:sign forKey:@"sign"];//签名
[dic setValue:body forKey:@"body"];//商品描述
[dic setValue:attach forKey:@"attach"];//附加信息
[dic setValue:pay_no forKey:@"out_trade_no"];//订单号
[dic setValue:should_pay forKey:@"total_fee"];//金额
[dic setValue:spbill_create_ip forKey:@"spbill_create_ip"];//终端IP
[dic setValue:notify_url forKey:@"notify_url"];//通知地址
[dic setValue:trade_type forKey:@"trade_type"];//交易类型
NSString *string = [dic XMLString];
[self WXHttp:string];
}
- (void)WXHttp:(NSString *)xml {
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//这里传入的xml字符串只是形似xml,但是不是正确是xml格式,需要使用af方法进行转义
manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"];
[manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
return xml;
}];
// 发起请求
[manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ;
//将微信返回的xml数据解析转义成字典
NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];
//判断返回的许可
if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) {
//发起微信支付,设置参数
PayReq *request = [[PayReq alloc] init];
request.partnerId = [dic objectForKey:@"mch_id"];
request.prepayId= [dic objectForKey:@"prepay_id"];
request.package = @"Sign=WXPay";
request.nonceStr= [dic objectForKey:@"nonce_str"];
//将当前事件转化成时间戳
NSDate *datenow = [NSDate date];
NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
UInt32 timeStamp =[timeSp intValue];
request.timeStamp= timeStamp;
DataMD5 *md5 = [[DataMD5 alloc] init];
request.sign=[md5 createMD5SingForPay:kWXAPP_ID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];
//调用微信
if ([WXApi isWXAppInstalled]) {
[WXApi sendReq:request];
} else {
[SVProgressHUD setMinimumDismissTimeInterval:1.0];
[SVProgressHUD showInfoWithStatus:@"请先安装微信"];
}
}else{
NSLog(@"err_code == %@",[dic objectForKey:@"err_code"]);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"error is %@",error);
}];
}
#pragma mark - 微信分享
+ (void)wxShareFromType:(NSNumber *)type Content:(NSString *)content UrlStr:(NSString *)urlStr {
// 分享图片到朋友圈
// WXMediaMessage *message = [WXMediaMessage message];
// [message setThumbImage:[UIImage imageNamed:@"iconLogo"]];
// if ([type isEqual:@0]) {
// message.title = @"";
// } else {
// message.title = content;
// }
// message.description = content;
// WXWebpageObject *webPage = [WXWebpageObject object];
// webPage.webpageUrl = urlStr;
// message.mediaObject = webPage;
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
req.text = content;
req.bText = YES;
// req.message = message;
if ([type isEqual:@0]) {
req.scene = WXSceneSession; // 好友
} else if ([type isEqual:@1]) {
req.scene = WXSceneTimeline; // 朋友圈
}
if ([WXApi isWXAppInstalled]) {
[WXApi sendReq:req];
} else {
[SVProgressHUD setMinimumDismissTimeInterval:1.5];
[SVProgressHUD showErrorWithStatus:@"没有安装微信"];
}
}