├── index.js
├── screenshot_1.png
├── screentshot_2.png
├── src
├── OpenShare+Alipay.h
├── OpenShareHeader.h
├── OpenShare+Renren.h
├── OpenShare+Weixin.h
├── OpenShare+Weibo.h
├── SocietyLoginManager.h
├── OpenShare+QQ.h
├── OpenShare+Alipay.m
├── OpenShare+Renren.m
├── OpenShare.h
├── SocietyLoginManager.m
├── OpenShare+Weibo.m
├── OpenShare+Weixin.m
├── OpenShare+QQ.m
└── OpenShare.m
├── package.json
└── README.md
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('react-native').NativeModules.SocietyLoginManager
2 |
--------------------------------------------------------------------------------
/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozillo/react-native-open-share/HEAD/screenshot_1.png
--------------------------------------------------------------------------------
/screentshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozillo/react-native-open-share/HEAD/screentshot_2.png
--------------------------------------------------------------------------------
/src/OpenShare+Alipay.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Alipay.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/6/4.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @interface OpenShare (Alipay)
12 | +(void)connectAlipay;
13 | +(void)AliPay:(NSString*)link Success:(paySuccess)success Fail:(payFail)fail;
14 | @end
15 |
--------------------------------------------------------------------------------
/src/OpenShareHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShareHeader.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/15.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #ifndef openshare_OpenShareHeader_h
10 | #define openshare_OpenShareHeader_h
11 | #import "OpenShare+QQ.h"
12 | #import "OpenShare+Weibo.h"
13 | #import "OpenShare+Weixin.h"
14 | #import "OpenShare+Renren.h"
15 | #import "OpenShare+Alipay.h"
16 | #endif
17 |
--------------------------------------------------------------------------------
/src/OpenShare+Renren.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Renren.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/19.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @interface OpenShare (Renren)
12 | +(void)connectRenrenWithAppId:(NSString *)appId AndAppKey:(NSString*)appKey;
13 | +(BOOL)isRenrenInstalled;
14 |
15 | +(void)shareToRenrenSession:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
16 | +(void)shareToRenrenTimeline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-open-share",
3 | "version": "0.1.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/mozillo/react-native-open-share.git"
12 | },
13 | "keywords": [
14 | "share",
15 | "react-native"
16 | ],
17 | "author": "mozillo",
18 | "license": "ISC",
19 | "bugs": {
20 | "url": "https://github.com/mozillo/react-native-open-share/issues"
21 | },
22 | "homepage": "https://github.com/mozillo/react-native-open-share#readme"
23 | }
24 |
--------------------------------------------------------------------------------
/src/OpenShare+Weixin.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Weixin.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/18.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @interface OpenShare (Weixin)
12 | /**
13 | * https://open.weixin.qq.com 在这里申请
14 | *
15 | * @param appId AppID
16 | */
17 | +(void)connectWeixinWithAppId:(NSString *)appId;
18 | +(BOOL)isWeixinInstalled;
19 |
20 | +(void)shareToWeixinSession:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
21 | +(void)shareToWeixinTimeline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
22 | +(void)shareToWeixinFavorite:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
23 | +(void)WeixinAuth:(NSString*)scope Success:(authSuccess)success Fail:(authFail)fail;
24 | +(void)WeixinPay:(NSString*)link Success:(paySuccess)success Fail:(payFail)fail;
25 | @end
26 |
--------------------------------------------------------------------------------
/src/OpenShare+Weibo.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Weibo.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/18.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @interface OpenShare (Weibo)
12 |
13 | /**
14 | * 可以点击「编辑」修改Bundle ID,要和这里的一致,否则auth的时候会返回error_code=21338
15 | *
16 | * @param appKey 申请到的appKey
17 | */
18 | +(void)connectWeiboWithAppKey:(NSString *)appKey;
19 | +(BOOL)isWeiboInstalled;
20 | /**
21 | * 分享到微博,微博只支持三种类型:文本/图片/链接。根据OSMessage自动判定想分享的类型。
22 | *
23 | * @param msg 要分享的msg
24 | * @param success 分享成功回调
25 | * @param fail 分享失败回调
26 | */
27 | +(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
28 |
29 | /**
30 | * 微博登录OAuth
31 | *
32 | * @param scope scope,如果不填写,默认是all
33 | * @param redirectURI 必须填写,可以通过http://open.weibo.com/apps/402180334/info/advanced编辑(后台不验证,但是必须填写一致)
34 | * @param success 登录成功回调
35 | * @param fail 登录失败回调
36 | */
37 | +(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail;
38 | @end
39 |
--------------------------------------------------------------------------------
/src/SocietyLoginManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CallBackTestManager.h
3 | // MarryNovo
4 | //
5 | // Created by Mot on 15/11/4.
6 | // Copyright © 2015年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "RCTBridgeModule.h"
10 |
11 | //重写NSLog,Debug模式下打印日志和当前行数
12 | #if DEBUG
13 | #define NSLog(FORMAT, ...) fprintf(stderr,"\nfunction:%s line:%d\n%s\n", __FUNCTION__, __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
14 | #else
15 | #define NSLog(FORMAT, ...) nil
16 | #endif
17 |
18 | #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
19 |
20 | //DEBUG 模式下打印日志,当前行 并弹出一个警告
21 | #ifdef DEBUG
22 | # define ULog(fmt, ...) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }
23 | #else
24 | # define ULog(...)
25 | #endif
26 |
27 | @interface SocietyLoginManager : NSObject
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/src/OpenShare+QQ.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+QQ.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/15.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @interface OpenShare (QQ)
12 | /**
13 | * 连接QQ平台。可以分享到:qq好友/qq空间。只需要appId:http://op.open.qq.com/index.php?mod=appinfo&act=main&appid=1103194207#mobile|center
14 | * 需要添加CFBundleURLSchemes:
15 | *
16 | * tencent1103194207
17 | * tencent1103194207.content
18 | * QQ41C1685F 16进制表示的appid,可以通过new Number(1103194207).toString(16).toUpperCase()获取。
19 | * @param appId 所申请的应用的APP ID
20 | */
21 | +(void)connectQQWithAppId:(NSString *)appId;
22 | +(BOOL)isQQInstalled;
23 |
24 | +(void)shareToQQFriends:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
25 | +(void)shareToQQZone:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
26 | +(void)shareToQQFavorites:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
27 | +(void)shareToQQDataline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
28 | +(void)QQAuth:(NSString*)scope Success:(authSuccess)success Fail:(authFail)fail;
29 | /**
30 | * 打开WPA临时会话
31 | *
32 | * @param qqNumber 要聊天的QQ号
33 | */
34 | +(void)chatWithQQNumber:(NSString*)qqNumber;
35 | /**
36 | * 打开某个群聊天。QQ客户端登录的QQ号,必须是groupNumber的成员才能聊天。
37 | *
38 | * @param groupNumber 群号码
39 | */
40 | +(void)chatInQQGroup:(NSString*)groupNumber;
41 | /**
42 | * 是否能处理这个openUrl,如果能就返回YES,并且按照callback处理,否则返回NO,交给下一个处理。
43 | *
44 | * @param url openURL
45 | * @param success success callback
46 | * @param fail fail callback
47 | *
48 | * @return 是否能处理给定的url
49 | */
50 | +(BOOL)QQ_handleOpenURL;
51 | @end
52 |
--------------------------------------------------------------------------------
/src/OpenShare+Alipay.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Alipay.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/6/4.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare+Alipay.h"
10 |
11 | @implementation OpenShare (Alipay)
12 | static NSString* schema=@"Alipay";
13 | /**
14 | * 支付宝支付参数都是从服务器获得的,所以不需要注册key。但是还是需要先connect向OpenShare注册,以便回调。
15 | */
16 | +(void)connectAlipay{
17 | [self set:schema Keys:@{@"schema":schema}];
18 | }
19 |
20 | +(BOOL)isAlipayInstalled{
21 | return [self canOpen:@"alipay://"];
22 | }
23 | +(void)AliPay:(NSString*)link Success:(paySuccess)success Fail:(payFail)fail{
24 | [self setPaySuccessCallback:success];
25 | [self setPayFailCallback:fail];
26 | if ([self isAlipayInstalled]) {
27 | //支付宝为了用户体验,会把截屏放在支付的后面当背景,可选项。当然也可以用其他的自己生成的UIImage,比如[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Default@2x" ofType:@"png"]]
28 | UIImage *screenShot= [self screenshot];
29 | //获取到fromAppUrlScheme,来设置截屏。
30 | NSString *linkStr=[self urlDecode:[link substringFromIndex:NSMaxRange([link rangeOfString:@"?"])]];
31 | NSDictionary *linkDic=[NSJSONSerialization JSONObjectWithData:[linkStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
32 | [[UIPasteboard generalPasteboard] setData:[NSKeyedArchiver archivedDataWithRootObject:@{@"image_data" :UIImagePNGRepresentation(screenShot),@"scheme" :linkDic[@"fromAppUrlScheme"]}] forPasteboardType:@"com.alipay.alipayClient.screenImage"];
33 | //END 设置截屏(可以不设置,注释掉这块代码即可。)。
34 |
35 | [self openURL:link];
36 | }
37 | }
38 | +(BOOL)Alipay_handleOpenURL{
39 | NSURL* url=[self returnedURL];
40 | if ([url.absoluteString rangeOfString:@"//safepay/"].location != NSNotFound) {
41 | NSError *err;
42 | NSDictionary *ret=[NSJSONSerialization JSONObjectWithData:[[self urlDecode:url.query]dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&err];
43 | if (err||ret[@"memo"]==[NSNull null]||[ret[@"memo"][@"ResultStatus"] intValue]!=9000) {
44 | if ([self payFailCallback]) {
45 | [self payFailCallback](ret,err?:[NSError errorWithDomain:@"alipay_pay" code:ret[@"memo"]!=[NSNull null]?[ret[@"memo"][@"ResultStatus"] intValue]:-1 userInfo:ret]);
46 | }
47 | }else{
48 | if ([self paySuccessCallback]) {
49 | [self paySuccessCallback](ret);
50 | }
51 | }
52 | return YES;
53 | }else{
54 | return NO;
55 | }
56 | }
57 | @end
58 |
--------------------------------------------------------------------------------
/src/OpenShare+Renren.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Renren.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/19.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare+Renren.h"
10 |
11 | @implementation OpenShare (Renren)
12 | static NSString* schema=@"Renren";
13 | +(void)connectRenrenWithAppId:(NSString *)appId AndAppKey:(NSString*)appKey{
14 | [self set:schema Keys:@{@"appid":appId,@"appkey":appKey}];
15 | }
16 | +(BOOL)isRenrenInstalled{
17 | return [self canOpen:@"renrenshare://share"];
18 | }
19 |
20 | +(void)shareToRenrenSession:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
21 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
22 | [self openURL:[self genRenrenShareUrl:msg to:0]];
23 | }
24 | }
25 | +(void)shareToRenrenTimeline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
26 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
27 | [self openURL:[self genRenrenShareUrl:msg to:1]];
28 | }
29 | }
30 | +(NSString*)genRenrenShareUrl:(OSMessage*)msg to:(int)shareTo{
31 | NSString *msgType=@"Text";
32 | NSMutableDictionary *dic=[[NSMutableDictionary alloc] initWithDictionary:@{@"title":msg.title}];
33 | if(msg.multimediaType==OSMultimediaTypeAudio){
34 | dic[@"description"]=msg.desc?:msg.title;
35 | dic[@"thumbData"]= msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(36, 36)];
36 | dic[@"url"]=msg.link;
37 | msgType=@"Voice";
38 | }else if(msg.multimediaType==OSMultimediaTypeVideo){
39 | dic[@"description"]=msg.desc?:msg.title;
40 | dic[@"thumbData"]= msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(36, 36)];
41 | dic[@"url"]=msg.link;
42 | msgType=@"Video";
43 | }else{
44 | if ([msg isEmpty:nil AndNotEmpty:@[@"image",@"link"]]) {
45 | //图文
46 | dic[@"description"]=msg.desc?:msg.title;
47 | dic[@"thumbData"]= msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(36, 36)];
48 | dic[@"url"]=msg.link;
49 | msgType=@"ImgText";
50 | }else if ([msg isEmpty:@[@"link"] AndNotEmpty:@[@"image"]]) {
51 | //图片
52 | dic[@"imageData"]= [self dataWithImage:msg.image];
53 | dic[@"thumbData"]= msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(36, 36)];
54 | msgType=@"ImgText";
55 | }else if ([msg isEmpty:@[@"link"] AndNotEmpty:@[@"image"]]) {
56 | //文本
57 | dic[@"text"]=msg.desc?:msg.title;
58 | if (msg.link) {
59 | dic[@"url"]=msg.link;
60 | }
61 | msgType=@"Text";
62 | }
63 | }
64 | [[UIPasteboard generalPasteboard] setData:[NSPropertyListSerialization dataWithPropertyList:dic format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil] forPasteboardType:@"renren_share"];
65 | return [NSString stringWithFormat:@"renrenshare://share?sdk_ver=1.0&app_id=%@&app_key=%@&callback=renrenshare%@&msgType=%@&target=%d&msgVer=1.0&msgData=renren_share",[self keyFor:schema][@"appid"],[self keyFor:schema][@"appkey"],[self keyFor:schema][@"appid"],msgType,shareTo];
66 | }
67 | /**
68 | * 人人网回调,人人网不传回分享结果。
69 | *
70 | * @return 是否是人人网打开的
71 | */
72 | +(BOOL)Renren_handleOpenURL{
73 | NSURL* url=[self returnedURL];
74 | if ([url.scheme hasPrefix:@"renrenshare"]) {
75 | if ([self shareSuccessCallback]) {
76 | [self shareSuccessCallback]([self message]);
77 | }
78 | return YES;
79 | }else{
80 | return NO;
81 | }
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/src/OpenShare.h:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare.h
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/13.
6 | // Copyright (c) 2015年 OpenShare. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | /**
12 | 分享类型,除了news以外,还可能是video/audio/app等。
13 | */
14 | typedef enum : NSUInteger {
15 | OSMultimediaTypeNews,
16 | OSMultimediaTypeAudio,
17 | OSMultimediaTypeVideo,
18 | OSMultimediaTypeApp,
19 | OSMultimediaTypeFile,
20 | OSMultimediaTypeUndefined
21 | } OSMultimediaType;
22 | /**
23 | * OSMessage保存分享消息数据。
24 | */
25 | @interface OSMessage : NSObject
26 | @property NSString* title;
27 | @property NSString* desc;
28 | @property NSString* link;
29 | @property UIImage *image;
30 | @property UIImage *thumbnail;
31 | @property OSMultimediaType multimediaType;
32 | //for 微信
33 | @property NSString* extInfo;
34 | @property NSString* mediaDataUrl;
35 | @property NSString* fileExt;
36 | @property (nonatomic, strong) NSData *file; /// 微信分享gif/文件
37 | /**
38 | * 判断emptyValueForKeys的value都是空的,notEmptyValueForKeys的value都不是空的。
39 | *
40 | * @param emptyValueForKeys 空值的key
41 | * @param notEmptyValueForKeys 非空值的key
42 | *
43 | * @return YES/NO
44 | */
45 | -(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys;
46 | @end
47 |
48 |
49 | typedef void (^shareSuccess)(OSMessage * message);
50 | typedef void (^shareFail)(OSMessage * message,NSError *error);
51 | typedef void (^authSuccess)(NSDictionary * message);
52 | typedef void (^authFail)(NSDictionary * message,NSError *error);
53 | typedef void (^paySuccess)(NSDictionary * message);
54 | typedef void (^payFail)(NSDictionary * message,NSError *error);
55 | /**
56 | 粘贴板数据编码方式,目前只有两种:
57 | 1. [NSKeyedArchiver archivedDataWithRootObject:data];
58 | 2. [NSPropertyListSerialization dataWithPropertyList:data format:NSPropertyListBinaryFormat_v1_0 options:0 error:&err];
59 | */
60 | typedef enum : NSUInteger {
61 | OSPboardEncodingKeyedArchiver,
62 | OSPboardEncodingPropertyListSerialization,
63 | } OSPboardEncoding;
64 | @interface OpenShare : NSObject
65 |
66 | /**
67 | * 设置平台的key
68 | *
69 | * @param platform 平台名称
70 | * @param key NSDictionary格式的key
71 | */
72 | +(void)set:(NSString*)platform Keys:(NSDictionary *)key;
73 | /**
74 | * 获取平台的key
75 | *
76 | * @param platform 平台名称,每个category自行决定。
77 | *
78 | * @return 平台的key(NSDictionary或nil)
79 | */
80 | +(NSDictionary *)keyFor:(NSString*)platform;
81 |
82 | /**
83 | * 通过UIApplication打开url
84 | *
85 | * @param url 需要打开的url
86 | */
87 | +(void)openURL:(NSString*)url;
88 | +(BOOL)canOpen:(NSString*)url;
89 | /**
90 | * 处理被打开时的openurl
91 | *
92 | * @param url openurl
93 | *
94 | * @return 如果能处理,就返回YES。够则返回NO
95 | */
96 | +(BOOL)handleOpenURL:(NSURL*)url;
97 | +(shareSuccess)shareSuccessCallback;
98 |
99 | +(shareFail)shareFailCallback;
100 |
101 | +(void)setShareSuccessCallback:(shareSuccess)suc;
102 |
103 | +(void)setShareFailCallback:(shareFail)fail;
104 |
105 | +(NSURL*)returnedURL;
106 |
107 | +(NSDictionary*)returnedData;
108 |
109 | +(void)setReturnedData:(NSDictionary*)retData;
110 |
111 | +(NSMutableDictionary *)parseUrl:(NSURL*)url;
112 |
113 | +(void)setMessage:(OSMessage*)msg;
114 |
115 | +(OSMessage*)message;
116 |
117 | +(BOOL)beginShare:(NSString*)platform Message:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail;
118 | +(BOOL)beginAuth:(NSString*)platform Success:(authSuccess)success Fail:(authFail)fail;
119 |
120 | +(NSString*)base64Encode:(NSString *)input;
121 | +(NSString*)base64Decode:(NSString *)input;
122 | +(NSString*)CFBundleDisplayName;
123 | +(NSString*)CFBundleIdentifier;
124 |
125 | +(void)setGeneralPasteboard:(NSString*)key Value:(NSDictionary*)value encoding:(OSPboardEncoding)encoding;
126 | +(NSDictionary*)generalPasteboardData:(NSString*)key encoding:(OSPboardEncoding)encoding;
127 | +(NSString*)base64AndUrlEncode:(NSString *)string;
128 | +(NSString*)urlDecode:(NSString*)input;
129 | + (UIImage *)screenshot;
130 |
131 | +(authSuccess)authSuccessCallback;
132 | +(authFail)authFailCallback;
133 |
134 | +(void)setPaySuccessCallback:(paySuccess)suc;
135 |
136 | +(void)setPayFailCallback:(payFail)fail;
137 |
138 | +(paySuccess)paySuccessCallback;
139 | +(payFail)payFailCallback;
140 |
141 | + (NSData *)dataWithImage:(UIImage *)image;
142 | + (NSData *)dataWithImage:(UIImage *)image scale:(CGSize)size;
143 |
144 | @end
145 |
146 |
147 |
--------------------------------------------------------------------------------
/src/SocietyLoginManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CallBackTestManager.m
3 | // MarryNovo
4 | //
5 | // Created by Mot on 15/11/4.
6 | // Copyright © 2015年 Facebook. All rights reserved.
7 | //
8 |
9 | #import "SocietyLoginManager.h"
10 | #import "RCTEventDispatcher.h"
11 | #import "OpenShareHeader.h"
12 |
13 | @implementation SocietyLoginManager
14 | @synthesize bridge = _bridge;
15 |
16 | RCT_EXPORT_MODULE();
17 |
18 | RCT_EXPORT_METHOD(call) {
19 | [self _callback];
20 | }
21 |
22 | RCT_EXPORT_METHOD(qqLogin) {
23 | [self _callQQLogin];
24 | }
25 |
26 | RCT_EXPORT_METHOD(wechatLogin) {
27 | [self _callWeichatLogin];
28 | }
29 |
30 | RCT_EXPORT_METHOD(weiboLogin) {
31 | [self _callWeiboLogin];
32 | }
33 |
34 |
35 | - (void)_callback {
36 | NSLog(@"Success call native modules");
37 | }
38 |
39 | -(void)_callQQLogin {
40 |
41 | [OpenShare QQAuth:@"get_user_info" Success:^(NSDictionary *message) {
42 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
43 | body:@{
44 | @"title": @"QQ登录成功",
45 | @"res": message
46 | }
47 | ];
48 |
49 | } Fail:^(NSDictionary *message, NSError *error) {
50 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
51 | body:@{
52 | @"title": @"QQ登录失败",
53 | @"res": message,
54 | @"error": error,
55 | }
56 | ];
57 | }];
58 | }
59 |
60 | -(void)_callWeichatLogin {
61 | [OpenShare WeixinAuth:@"snsapi_userinfo" Success:^(NSDictionary *message) {
62 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
63 | body:@{
64 | @"title": @"微信登录成功",
65 | @"res": message
66 | }
67 | ];
68 |
69 | } Fail:^(NSDictionary *message, NSError *error) {
70 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
71 | body:@{
72 | @"title": @"微信登录失败",
73 | @"res": message,
74 | @"error": error,
75 | }
76 | ];
77 | }];
78 | }
79 |
80 | //处理 返回数据中的expirationDate值,因为值的格式有问题,转换成 string 后才能符合 json 的格式要求。 ********开始********
81 | //Commit by Parry at 2016-01-26
82 |
83 | - (NSMutableDictionary*)change: (NSDictionary *)message {
84 |
85 | NSMutableDictionary* data = [message mutableCopy];
86 | if ([message objectForKey:@"expirationDate"]) {
87 |
88 | NSDateFormatter *dateToStringFormatter = [[NSDateFormatter alloc] init];
89 | [dateToStringFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
90 |
91 | NSDate *date= [data objectForKey:@"expirationDate"];
92 | NSString *strDate = [dateToStringFormatter stringFromDate:date];
93 |
94 | data = [message mutableCopy];
95 |
96 | [data setObject:strDate forKey:@"expirationDate"];
97 | }
98 | return data;
99 |
100 | }
101 |
102 | //处理 返回数据中的expirationDate值,因为值的格式有问题,转换成 string 后才能符合 json 的格式要求。 ********结束********
103 |
104 | -(void)_callWeiboLogin {
105 | [OpenShare WeiboAuth:@"all" redirectURI:@"http://sns.whalecloud.com" Success:^(NSDictionary *message) {
106 |
107 | NSMutableDictionary* data = [self change:message];
108 |
109 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
110 | body:@{
111 | @"title": @"微博登录成功",
112 | @"res": data,
113 | }
114 | ];
115 | } Fail:^(NSDictionary *message, NSError *error) {
116 |
117 | NSMutableDictionary* data = [self change:message];
118 |
119 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"managerCallback"
120 | body:@{
121 | @"title": @"微博登录失败",
122 | @"res": data,
123 | @"error": error
124 | }
125 | ];
126 | }];
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-open-share
2 | Integrate wechat,weibo,qq,alipay [share,payment,login] to your react native application.
3 | ### built from [OpenShare](https://github.com/100apps/openshare)
4 | ## Screen Shot
5 |
6 |
7 |
8 |
9 | ##Installation
10 | 1.Run `npm install https://github.com/mozillo/react-native-open-share.git --save` in your project directory.
11 |
12 | 2.Select your project , and find your [ ProjectName ] directory , Select it and right click "New Group", and rename it to "OpenShare", right click "Add Files to 'App' ...", select all files under the ./node_modules/react-native-open-share/src/ directory , and added them to OpenShare group.
13 |
14 | 3.Edit Info.plist, Open As => Source code, append ***new Info.plist code*** content after
15 |
16 | ```
17 |
18 |
19 |
20 |
21 | ```
22 |
23 | new Info.plist code:
24 | ```
25 | CFBundleURLTypes
26 |
27 |
28 | CFBundleURLName
29 | RNShare
30 | CFBundleURLSchemes
31 |
32 |
33 | wxd930ea5d5a258f4f
34 |
35 | tencent1103194207
36 | tencent1103194207.content
37 | QQ41C1685F
38 |
39 | wb402180334
40 |
41 | renrenshare228525
42 |
43 | fb776442542471056
44 |
45 |
46 |
47 |
48 | ```
49 |
50 | 4.Edit AppDelegate.m :
51 | Add header file:
52 | ```
53 | #import "OpenShareHeader.h"
54 | ```
55 | Add these code to "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" :
56 |
57 | ```
58 | [OpenShare connectQQWithAppId:@"1103194207"];
59 | [OpenShare connectWeiboWithAppKey:@"402180334"];
60 | [OpenShare connectWeixinWithAppId:@"wxd930ea5d5a258f4f"];
61 | [OpenShare connectRenrenWithAppId:@"228525" AndAppKey:@"1dd8cba4215d4d4ab96a49d3058c1d7f"];
62 | ```
63 |
64 | and add this method after "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" block:
65 |
66 | ```
67 | -(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
68 | //第二步:添加回调
69 | if ([OpenShare handleOpenURL:url]) {
70 | return YES;
71 | }
72 | //这里可以写上其他OpenShare不支持的客户端的回调,比如支付宝等。
73 | return YES;
74 | }
75 | ```
76 |
77 | ###Done.
78 |
79 | ## Usage
80 |
81 | example:
82 |
83 | ```
84 | 'use strict';
85 |
86 | var React = require('react-native');
87 | var {
88 | AppRegistry,
89 | StyleSheet,
90 | Text,
91 | View,
92 | TouchableOpacity,
93 | DeviceEventEmitter,
94 | AlertIOS,
95 | } = React;
96 |
97 | var openShare = require('react-native-open-share');
98 |
99 | var App = React.createClass({
100 |
101 | _wechatLogin: function() {
102 | var _this = this;
103 | openShare.wechatLogin();
104 |
105 | if(!_this.wechatLogin) {
106 | _this.wechatLogin = DeviceEventEmitter.addListener(
107 | 'managerCallback',
108 | (response) => {
109 | AlertIOS.alert(
110 | 'response',
111 | JSON.stringify(response)
112 | );
113 |
114 | _this.wechatLogin.remove();
115 | delete _this.wechatLogin;
116 | }
117 | );
118 | }
119 | },
120 |
121 | render: function() {
122 | return (
123 |
124 |
125 |
126 | WeChat Login
127 |
128 |
129 |
130 | Welcome to React Native!
131 |
132 |
133 | To get started, edit index.ios.js
134 |
135 |
136 | Press Cmd+R to reload,{'\n'}
137 | Cmd+D or shake for dev menu
138 |
139 |
140 | );
141 | }
142 | });
143 |
144 | var styles = StyleSheet.create({
145 | container: {
146 | flex: 1,
147 | justifyContent: 'center',
148 | alignItems: 'center',
149 | backgroundColor: '#F5FCFF',
150 | },
151 | welcome: {
152 | fontSize: 20,
153 | textAlign: 'center',
154 | margin: 10,
155 | },
156 | instructions: {
157 | textAlign: 'center',
158 | color: '#333333',
159 | marginBottom: 5,
160 | },
161 | });
162 |
163 | AppRegistry.registerComponent('App', () => App);
164 |
165 | ```
166 | ## current API
167 |
168 | ```
169 | openShare.qqLogin();
170 | openShare.wechatLogin();
171 | openShare.weiboLogin();
172 | ```
173 |
174 | ##Other
175 | ```
176 |
177 | wechat access token request:
178 | https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
179 |
180 | wechat user profile request:
181 | https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
182 |
183 |
--------------------------------------------------------------------------------
/src/OpenShare+Weibo.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Weibo.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/18.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare+Weibo.h"
10 |
11 | @implementation OpenShare (Weibo)
12 | static NSString *schema=@"Weibo";
13 | +(void)connectWeiboWithAppKey:(NSString *)appKey{
14 | [self set:schema Keys:@{@"appKey":appKey}];
15 | }
16 | +(BOOL)isWeiboInstalled{
17 | return [self canOpen:@"weibosdk://request"];
18 | }
19 | +(void)shareToWeibo:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
20 | if (![self beginShare:schema Message:msg Success:success Fail:fail]) {
21 | return;
22 | }
23 | NSDictionary *message;
24 | if ([msg isEmpty:@[@"link" ,@"image"] AndNotEmpty:@[@"title"] ]) {
25 | //text类型分享
26 | message= @{
27 | @"__class" : @"WBMessageObject",
28 | @"text" :msg.title
29 | };
30 | }else if ([msg isEmpty:@[@"link" ] AndNotEmpty:@[@"title",@"image"] ]) {
31 | //图片类型分享
32 | message=@{
33 | @"__class" : @"WBMessageObject",
34 | @"imageObject":@{
35 | @"imageData":[self dataWithImage:msg.image]
36 | },
37 | @"text" : msg.title
38 | };
39 |
40 | }else if ([msg isEmpty:nil AndNotEmpty:@[@"title",@"link" ,@"image"] ]) {
41 | //链接类型分享
42 | message=@{
43 | @"__class" : @"WBMessageObject",
44 | @"mediaObject":@{
45 | @"__class" : @"WBWebpageObject",
46 | @"description": msg.desc?:msg.title,
47 | @"objectID" : @"identifier1",
48 | @"thumbnailData":msg.thumbnail ? [self dataWithImage:msg.thumbnail] : [self dataWithImage:msg.image scale:CGSizeMake(100, 100)],
49 | @"title": msg.title,
50 | @"webpageUrl":msg.link
51 | }
52 |
53 | };
54 | }
55 | NSString *uuid=[[NSUUID UUID] UUIDString];
56 | NSArray *messageData=@[
57 | @{@"transferObject":[NSKeyedArchiver archivedDataWithRootObject:@{
58 | @"__class" :@"WBSendMessageToWeiboRequest",
59 | @"message":message,
60 | @"requestID" :uuid,
61 | }]},
62 | @{@"userInfo":[NSKeyedArchiver archivedDataWithRootObject:@{}]},
63 |
64 | @{@"app":[NSKeyedArchiver archivedDataWithRootObject:@{ @"appKey" : [self keyFor:schema][@"appKey"],@"bundleID" : [self CFBundleIdentifier]}]}
65 | ];
66 | [UIPasteboard generalPasteboard].items=messageData;
67 | [self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
68 | }
69 |
70 | +(void)WeiboAuth:(NSString*)scope redirectURI:(NSString*)redirectURI Success:(authSuccess)success Fail:(authFail)fail{
71 | if (![self beginAuth:schema Success:success Fail:fail]) {
72 | return;
73 | }
74 | NSString *uuid=[[NSUUID UUID] UUIDString];
75 | NSArray *authData=@[
76 | @{@"transferObject":[NSKeyedArchiver archivedDataWithRootObject:@{
77 | @"__class" :@"WBAuthorizeRequest",
78 | @"redirectURI":redirectURI,
79 | @"requestID" :uuid,
80 | @"scope": scope?:@"all"
81 | }]},
82 | @{@"userInfo":[NSKeyedArchiver archivedDataWithRootObject:@{
83 | @"mykey":@"as you like",
84 | @"SSO_From" : @"SendMessageToWeiboViewController"
85 | }]
86 | },
87 |
88 | @{@"app":[NSKeyedArchiver archivedDataWithRootObject:@{
89 | @"appKey" :[self keyFor:schema][@"appKey"],
90 | @"bundleID" : [self CFBundleIdentifier],
91 | @"name" :[self CFBundleDisplayName]
92 | }]
93 | }
94 | ];
95 | [UIPasteboard generalPasteboard].items=authData;
96 | [self openURL:[NSString stringWithFormat:@"weibosdk://request?id=%@&sdkversion=003013000",uuid]];
97 | }
98 |
99 | +(BOOL)Weibo_handleOpenURL{
100 | NSURL* url=[self returnedURL];
101 | if ([url.scheme hasPrefix:@"wb"]) {
102 | NSArray *items=[UIPasteboard generalPasteboard].items;
103 | NSMutableDictionary *ret=[NSMutableDictionary dictionaryWithCapacity:items.count];
104 | for (NSDictionary *item in items) {
105 | for (NSString *k in item) {
106 | ret[k]=[k isEqualToString:@"sdkVersion"]?item[k]:[NSKeyedUnarchiver unarchiveObjectWithData:item[k]];
107 | }
108 | }
109 | NSDictionary *transferObject=ret[@"transferObject"];
110 | if ([transferObject[@"__class"] isEqualToString:@"WBAuthorizeResponse"]) {
111 | //auth
112 | if ([transferObject[@"statusCode"] intValue]==0) {
113 | if ([self authSuccessCallback]) {
114 | [self authSuccessCallback](transferObject);
115 | }
116 | }else{
117 | if ([self authFailCallback]) {
118 | NSError *err=[NSError errorWithDomain:@"weibo_auth_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];
119 | [self authFailCallback](transferObject,err);
120 | }
121 | }
122 | }else if ([transferObject[@"__class"] isEqualToString:@"WBSendMessageToWeiboResponse"]) {
123 | //分享回调
124 | if ([transferObject[@"statusCode"] intValue]==0) {
125 | if ([self shareSuccessCallback]) {
126 | [self shareSuccessCallback]([self message]);
127 | }
128 | }else{
129 | if ([self shareFailCallback]) {
130 | NSError *err=[NSError errorWithDomain:@"weibo_share_response" code:[transferObject[@"statusCode"] intValue] userInfo:transferObject];
131 | [self shareFailCallback]([self message],err);
132 | }
133 | }
134 | }
135 | return YES;
136 | } else{
137 | return NO;
138 | }
139 | }
140 |
141 |
142 | @end
143 |
--------------------------------------------------------------------------------
/src/OpenShare+Weixin.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+Weixin.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/18.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare+Weixin.h"
10 |
11 | @implementation OpenShare (Weixin)
12 | static NSString *schema=@"Weixin";
13 | +(void)connectWeixinWithAppId:(NSString *)appId{
14 | [self set:schema Keys:@{@"appid":appId}];
15 |
16 | }
17 | +(BOOL)isWeixinInstalled{
18 | return [self canOpen:@"weixin://"];
19 | }
20 |
21 | +(void)shareToWeixinSession:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
22 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
23 | [self openURL:[self genWeixinShareUrl:msg to:0]];
24 | }
25 | }
26 | +(void)shareToWeixinTimeline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
27 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
28 | [self openURL:[self genWeixinShareUrl:msg to:1]];
29 | }
30 | }
31 | +(void)shareToWeixinFavorite:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
32 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
33 | [self openURL:[self genWeixinShareUrl:msg to:2]];
34 | }
35 | }
36 |
37 |
38 | /**
39 | * 把msg分享到shareTO
40 | *
41 | * @param msg OSmessage
42 | * @param shareTo 0是好友/1是QQ空间。
43 | *
44 | * @return 需要打开的url
45 | */
46 | +(NSString*)genWeixinShareUrl:(OSMessage*)msg to:(int)shareTo{
47 | NSMutableDictionary *dic=[[NSMutableDictionary alloc] initWithDictionary:@{@"result":@"1",@"returnFromApp" :@"0",@"scene" : [NSString stringWithFormat:@"%d",shareTo],@"sdkver" : @"1.5",@"command" : @"1010"}];
48 | if (msg.multimediaType==OSMultimediaTypeNews) {
49 | msg.multimediaType=0;
50 | }
51 | if (!msg.multimediaType) {
52 | //不指定类型
53 | if ([msg isEmpty:@[@"image",@"link", @"file"] AndNotEmpty:@[@"title"]]) {
54 | //文本
55 | dic[@"command"]=@"1020";
56 | dic[@"title"]=msg.title;
57 | }else if([msg isEmpty:@[@"link"] AndNotEmpty:@[@"image"]]){
58 | //图片
59 | dic[@"title"]=msg.title?:@"";
60 | dic[@"fileData"]= [self dataWithImage:msg.image];
61 | dic[@"thumbData"]=msg.thumbnail ? [self dataWithImage:msg.thumbnail] : [self dataWithImage:msg.image scale:CGSizeMake(100, 100)];
62 | dic[@"objectType"]=@"2";
63 | }else if([msg isEmpty:nil AndNotEmpty:@[@"link",@"title",@"image"]]){
64 | //有链接。
65 | dic[@"description"]=msg.desc?:msg.title;
66 | dic[@"mediaUrl"]=msg.link;
67 | dic[@"objectType"]=@"5";
68 | dic[@"thumbData"]=msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(100, 100)];
69 | dic[@"title"] =msg.title;
70 | } else if ([msg isEmpty:@[@"link"] AndNotEmpty:@[@"file"]]) {
71 | //gif
72 | dic[@"fileData"]= msg.file ? msg.file : [self dataWithImage:msg.image];
73 | dic[@"thumbData"]=msg.thumbnail ? [self dataWithImage:msg.thumbnail] : [self dataWithImage:msg.image scale:CGSizeMake(100, 100)];
74 | dic[@"objectType"]=@"8";
75 | }
76 | }else if(msg.multimediaType==OSMultimediaTypeAudio){
77 | //music
78 | dic[@"description"]=msg.desc?:msg.title;
79 | dic[@"mediaUrl"]=msg.link;
80 | dic[@"mediaDataUrl"]=msg.mediaDataUrl;
81 | dic[@"objectType"]=@"3";
82 | dic[@"thumbData"]=msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(100, 100)];;
83 | dic[@"title"] =msg.title;
84 | }else if(msg.multimediaType==OSMultimediaTypeVideo){
85 | //video
86 | dic[@"description"]=msg.desc?:msg.title;
87 | dic[@"mediaUrl"]=msg.link;
88 | dic[@"objectType"]=@"4";
89 | dic[@"thumbData"]=msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(100, 100)];;
90 | dic[@"title"] =msg.title;
91 | }else if(msg.multimediaType==OSMultimediaTypeApp){
92 | //app
93 | dic[@"description"]=msg.desc?:msg.title;
94 | if(msg.extInfo)dic[@"extInfo"]=msg.extInfo;
95 | dic[@"fileData"]=[self dataWithImage:msg.image];
96 | dic[@"mediaUrl"]=msg.link;
97 | dic[@"objectType"]=@"7";
98 | dic[@"thumbData"]=msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(100, 100)];;
99 | dic[@"title"] =msg.title;
100 | }else if(msg.multimediaType==OSMultimediaTypeFile){
101 | //file
102 | dic[@"description"]=msg.desc?:msg.title;
103 | dic[@"fileData"]=msg.file;
104 | dic[@"objectType"]=@"6";
105 | dic[@"fileExt"]=msg.fileExt?:@"";
106 | dic[@"thumbData"]=msg.thumbnail? [self dataWithImage:msg.thumbnail]:[self dataWithImage:msg.image scale:CGSizeMake(100, 100)];;
107 | dic[@"title"] =msg.title;
108 | }
109 | NSData *output=[NSPropertyListSerialization dataWithPropertyList:@{[self keyFor:schema][@"appid"]:dic} format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
110 | [[UIPasteboard generalPasteboard] setData:output forPasteboardType:@"content"];
111 | return [NSString stringWithFormat:@"weixin://app/%@/sendreq/?",[self keyFor:schema][@"appid"]];
112 | }
113 |
114 |
115 | /**
116 | * 注意:微信登录权限仅限已获得认证的开发者申请,请先进行开发者认证
117 | *
118 | * @param scope scope
119 | * @param success 登录成功回调
120 | * @param fail 登录失败回调
121 | */
122 | +(void)WeixinAuth:(NSString*)scope Success:(authSuccess)success Fail:(authFail)fail{
123 | if ([self beginAuth:schema Success:success Fail:fail]) {
124 | [self openURL:[NSString stringWithFormat:@"weixin://app/%@/auth/?scope=%@&state=Weixinauth",[self keyFor:schema][@"appid"],scope]];
125 | }
126 | }
127 | /**
128 | * 微信支付,不同于分享和登录,由于参数是服务器生成的,所以不需要connect。
129 | *
130 | * @param link 服务器返回的link,以供直接打开
131 | * @param success 微信支付成功的回调
132 | * @param fail 微信支付失败的回调
133 | */
134 | +(void)WeixinPay:(NSString*)link Success:(paySuccess)success Fail:(payFail)fail{
135 | [self setPaySuccessCallback:success];
136 | [self setPayFailCallback:fail];
137 | [self openURL:link];
138 | }
139 |
140 | +(BOOL)Weixin_handleOpenURL{
141 | NSURL* url=[self returnedURL];
142 | if ([url.scheme hasPrefix:@"wx"]) {
143 | NSDictionary *retDic=[NSPropertyListSerialization propertyListWithData:[[UIPasteboard generalPasteboard] dataForPasteboardType:@"content"]?:[[NSData alloc] init] options:0 format:0 error:nil][[self keyFor:schema][@"appid"]];
144 | NSLog(@"retDic\n%@",retDic);
145 | if ([url.absoluteString rangeOfString:@"://oauth"].location != NSNotFound) {
146 | //login succcess
147 | if ([self authSuccessCallback]) {
148 | [self authSuccessCallback]([self parseUrl:url]);
149 | }
150 | }else if([url.absoluteString rangeOfString:@"://pay/"].location != NSNotFound){
151 | NSDictionary *urlMap=[self parseUrl:url];
152 | if ([urlMap[@"ret"] intValue]==0) {
153 | if ([self paySuccessCallback]) {
154 | [self paySuccessCallback](urlMap);
155 | }
156 | }else{
157 | if ([self payFailCallback]) {
158 | [self payFailCallback](urlMap,[NSError errorWithDomain:@"weixin_pay" code:[urlMap[@"ret"] intValue] userInfo:retDic]);
159 | }
160 | }
161 | }else{
162 | if (retDic[@"state"]&&[retDic[@"state"] isEqualToString:@"Weixinauth"]&&[retDic[@"result"] intValue]!=0) {
163 | //登录失败
164 | if ([self authFailCallback]) {
165 | [self authFailCallback](retDic,[NSError errorWithDomain:@"weixin_auth" code:[retDic[@"result"] intValue] userInfo:retDic]);
166 | }
167 | }else if([retDic[@"result"] intValue]==0){
168 | //分享成功
169 | if ([self shareSuccessCallback]) {
170 | [self shareSuccessCallback]([self message]);
171 | }
172 | }else{
173 | //分享失败
174 | if ([self shareFailCallback]) {
175 | [self shareFailCallback]([self message],[NSError errorWithDomain:@"weixin_share" code:[retDic[@"result"] intValue] userInfo:retDic]);
176 | }
177 | }
178 |
179 | }
180 | return YES;
181 | }else{
182 | return NO;
183 | }
184 | }
185 | @end
186 |
--------------------------------------------------------------------------------
/src/OpenShare+QQ.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare+QQ.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/15.
6 | // Copyright (c) 2015年 OpenShare . All rights reserved.
7 | //
8 |
9 | #import "OpenShare+QQ.h"
10 |
11 | @implementation OpenShare (QQ)
12 | static NSString* schema=@"QQ";
13 | enum
14 | {
15 | kQQAPICtrlFlagQZoneShareOnStart = 0x01,
16 | kQQAPICtrlFlagQZoneShareForbid = 0x02,
17 | kQQAPICtrlFlagQQShare = 0x04,
18 | kQQAPICtrlFlagQQShareFavorites = 0x08, //收藏
19 | kQQAPICtrlFlagQQShareDataline = 0x10, //数据线
20 | };
21 |
22 | +(void)connectQQWithAppId:(NSString *)appId{
23 | [self set:schema Keys:@{@"appid":appId,@"callback_name":[NSString stringWithFormat:@"QQ%02llx",[appId longLongValue]]}];
24 | }
25 | +(BOOL)isQQInstalled{
26 | return [self canOpen:@"mqqapi://"];
27 | }
28 | +(void)shareToQQFriends:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
29 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
30 | [self openURL:[self genShareUrl:msg to:0]];
31 | }
32 | }
33 | +(void)shareToQQZone:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
34 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
35 | [self openURL:[self genShareUrl:msg to:kQQAPICtrlFlagQZoneShareOnStart]];
36 | }
37 | }
38 | +(void)shareToQQFavorites:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
39 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
40 | [self openURL:[self genShareUrl:msg to:kQQAPICtrlFlagQQShareFavorites]];
41 | }
42 | }
43 | +(void)shareToQQDataline:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
44 | if ([self beginShare:schema Message:msg Success:success Fail:fail]) {
45 | [self openURL:[self genShareUrl:msg to:kQQAPICtrlFlagQQShareDataline]];
46 | }
47 | }
48 |
49 | +(void)QQAuth:(NSString*)scope Success:(authSuccess)success Fail:(authFail)fail{
50 | if ([self beginAuth:schema Success:success Fail:fail]) {
51 | NSDictionary *authData=@{@"app_id" : [self keyFor:schema][@"appid"],
52 | @"app_name" : [self CFBundleDisplayName],
53 | //@"bundleid":[self CFBundleIdentifier],//或者有,或者正确(和后台配置一致),建议不填写。
54 | @"client_id" :[self keyFor:schema][@"appid"],
55 | @"response_type" : @"token",
56 | @"scope" : scope,//@"get_user_info,get_simple_userinfo,add_album,add_idol,add_one_blog,add_pic_t,add_share,add_topic,check_page_fans,del_idol,del_t,get_fanslist,get_idollist,get_info,get_other_info,get_repost_list,list_album,upload_pic,get_vip_info,get_vip_rich_info,get_intimate_friends_weibo,match_nick_tips_weibo",
57 | @"sdkp" :@"i",
58 | @"sdkv" : @"2.9",
59 | @"status_machine" : [[UIDevice currentDevice] model],
60 | @"status_os" : [[UIDevice currentDevice] systemVersion],
61 | @"status_version" : [[UIDevice currentDevice] systemVersion]
62 | };
63 |
64 | [self setGeneralPasteboard:[@"com.tencent.tencent" stringByAppendingString:[self keyFor:schema][@"appid"]] Value:authData encoding:OSPboardEncodingKeyedArchiver];
65 | [self openURL:[NSString stringWithFormat:@"mqqOpensdkSSoLogin://SSoLogin/tencent%@/com.tencent.tencent%@?generalpastboard=1",[self keyFor:schema][@"appid"],[self keyFor:schema][@"appid"]]];
66 | }
67 | }
68 |
69 | /**
70 | * 把msg分享到shareTO
71 | *
72 | * @param msg OSmessage
73 | * @param shareTo 0是好友/1是QQ空间。
74 | *
75 | * @return 需要打开的url
76 | */
77 | +(NSString*)genShareUrl:(OSMessage*)msg to:(int)shareTo{
78 | NSMutableString *ret=[[NSMutableString alloc] initWithString:@"mqqapi://share/to_fri?thirdAppDisplayName="];
79 | [ret appendString:[self base64Encode:[self CFBundleDisplayName]]];
80 | [ret appendString:@"&version=1&cflag="];
81 | [ret appendFormat:@"%d",shareTo];
82 | [ret appendString:@"&callback_type=scheme&generalpastboard=1"];
83 | [ret appendString:@"&callback_name="];
84 | [ret appendString:[self keyFor:schema][@"callback_name"]];
85 | [ret appendString:@"&src_type=app&shareType=0&file_type="];
86 | //修正如果有link,则默认是news分享类型。
87 | if (msg.link&&!msg.multimediaType) {
88 | msg.multimediaType=OSMultimediaTypeNews;
89 | }
90 | if ([msg isEmpty:@[@"image",@"link" ] AndNotEmpty:@[@"title"]]) {
91 | //纯文本分享。
92 | [ret appendString:@"text&file_data="];
93 | [ret appendString:[self base64AndUrlEncode:msg.title]];
94 | }else if([msg isEmpty:@[@"link"] AndNotEmpty:@[@"title",@"image",@"desc"]]){
95 | //图片分享
96 | NSDictionary *data=@{@"file_data":[self dataWithImage:msg.image],
97 | @"previewimagedata":msg.thumbnail? [self dataWithImage:msg.thumbnail] :[self dataWithImage:msg.image scale:CGSizeMake(36, 36)]
98 | };
99 | [self setGeneralPasteboard:@"com.tencent.mqq.api.apiLargeData" Value:data encoding: OSPboardEncodingKeyedArchiver];
100 | [ret appendString:@"img&title="];
101 | [ret appendString:[self base64Encode:msg.title]];
102 | [ret appendString:@"&objectlocation=pasteboard&description="];
103 | [ret appendString:[self base64Encode:msg.desc]];
104 | }else if ([msg isEmpty:nil AndNotEmpty:@[@"title",@"desc",@"image",@"link",@"multimediaType"]]) {
105 | //新闻/多媒体分享(图片加链接)发送新闻消息 预览图像数据,最大1M字节 URL地址,必填,最长512个字符 via QQApiInterfaceObject.h
106 | NSDictionary *data=@{@"previewimagedata":[self dataWithImage:msg.image]};
107 | [self setGeneralPasteboard:@"com.tencent.mqq.api.apiLargeData" Value:data encoding: OSPboardEncodingKeyedArchiver];
108 | NSString *msgType=@"news";
109 | if (msg.multimediaType==OSMultimediaTypeAudio) {
110 | msgType=@"audio";
111 | }else if(msg.multimediaType==OSMultimediaTypeVideo){
112 | //QQ没有video类型。客户端会自动判断。
113 | // msgType=@"video";
114 | }
115 | [ret appendFormat:@"%@&title=%@&url=%@&description=%@&objectlocation=pasteboard",msgType,[self base64AndUrlEncode:msg.title],[self base64AndUrlEncode:msg.link],[self base64AndUrlEncode:msg.desc]];
116 | }
117 | return ret;
118 | }
119 | +(BOOL)QQ_handleOpenURL{
120 | NSURL* url=[self returnedURL];
121 | if ([url.scheme hasPrefix:@"QQ"]) {
122 | //分享
123 | NSDictionary *dic=[self parseUrl:url];
124 | if (dic[@"error_description"]) {
125 | [dic setValue:[self base64Decode:dic[@"error_description"]] forKey:@"error_description"];
126 | }
127 | if ([dic[@"error"] intValue]!=0) {
128 | NSError *err=[NSError errorWithDomain:@"response_from_qq" code:[dic[@"error"] intValue] userInfo:dic];
129 | if ([self shareFailCallback]) {
130 | [self shareFailCallback]([self message],err);
131 | }
132 | }else{
133 | if ([self shareSuccessCallback]) {
134 | [self shareSuccessCallback]([self message]);
135 | }
136 | }
137 | return YES;
138 | }else if([url.scheme hasPrefix:@"tencent"]){
139 | //登陆auth
140 | NSDictionary *ret=[self generalPasteboardData:[@"com.tencent.tencent" stringByAppendingString:[self keyFor:schema][@"appid"]] encoding:OSPboardEncodingKeyedArchiver];
141 | if (ret[@"ret"]&&[ret[@"ret"] intValue]==0) {
142 | if ( [self authSuccessCallback]) {
143 | [self authSuccessCallback](ret);
144 | }
145 | }else{
146 | NSError *err=[NSError errorWithDomain:@"auth_from_QQ" code:-1 userInfo:ret];
147 | if ([self authFailCallback]) {
148 | [self authFailCallback](ret,err);
149 | }
150 | }
151 | return YES;
152 | }
153 | else{
154 | return NO;
155 | }
156 | }
157 | +(void)chatWithQQNumber:(NSString*)qqNumber{
158 | [self openURL:[NSString stringWithFormat:@"mqqwpa://im/chat?uin=%@&thirdAppDisplayName=%@&callback_name=%@&src_type=app&version=1&chat_type=wpa&callback_type=scheme",qqNumber,[self base64Encode:[self CFBundleDisplayName]],[self keyFor:schema][@"callback_name"]]];
159 | }
160 | +(void)chatInQQGroup:(NSString*)groupNumber{
161 | [self openURL:[NSString stringWithFormat:@"mqqwpa://im/chat?uin=%@&thirdAppDisplayName=%@&callback_name=%@&src_type=app&version=1&chat_type=group&callback_type=scheme",groupNumber,[self base64Encode:[self CFBundleDisplayName]],[self keyFor:schema][@"callback_name"]]];
162 | }
163 | @end
164 |
--------------------------------------------------------------------------------
/src/OpenShare.m:
--------------------------------------------------------------------------------
1 | //
2 | // OpenShare.m
3 | // openshare
4 | //
5 | // Created by LiuLogan on 15/5/13.
6 | // Copyright (c) 2015年 OpenShare. All rights reserved.
7 | //
8 |
9 | #import "OpenShare.h"
10 |
11 | @implementation OpenShare
12 | /**
13 | * 用于保存各个平台的key。每个平台需要的key/appid不一样,所以用dictionary保存。
14 | */
15 | static NSMutableDictionary *keys;
16 |
17 | +(void)set:(NSString*)platform Keys:(NSDictionary *)key{
18 | if (!keys) {
19 | keys=[[NSMutableDictionary alloc] init];
20 | }
21 | keys[platform]=key;
22 | }
23 | +(NSDictionary *)keyFor:(NSString*)platform{
24 | return [keys valueForKey:platform]?keys[platform]:nil;
25 | }
26 |
27 | +(void)openURL:(NSString*)url{
28 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
29 | }
30 | +(BOOL)canOpen:(NSString*)url{
31 | return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]];
32 | }
33 | +(BOOL)handleOpenURL:(NSURL*)openUrl{
34 | returnedURL=openUrl;
35 | for (NSString *key in keys) {
36 | SEL sel=NSSelectorFromString([key stringByAppendingString:@"_handleOpenURL"]);
37 | if ([self respondsToSelector:sel]) {
38 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
39 | [self methodSignatureForSelector:sel]];
40 | [invocation setSelector:sel];
41 | [invocation setTarget:self];
42 | [invocation invoke];
43 | BOOL returnValue;
44 | [invocation getReturnValue:&returnValue];
45 | if (returnValue) {//如果这个url能处理,就返回YES,否则,交给下一个处理。
46 | return YES;
47 | }
48 | }else{
49 | NSLog(@"fatal error: %@ is should have a method: %@",key,[key stringByAppendingString:@"_handleOpenURL"]);
50 | }
51 | }
52 | return NO;
53 | }
54 |
55 | #pragma mark 分享/auth以后,应用被调起,回调。
56 | static NSURL* returnedURL;
57 | static NSDictionary *returnedData;
58 | static shareSuccess shareSuccessCallback;
59 | static shareFail shareFailCallback;
60 |
61 | static authSuccess authSuccessCallback;
62 | static authFail authFailCallback;
63 |
64 | static paySuccess paySuccessCallback;
65 | static payFail payFailCallback;
66 |
67 | static OSMessage *message;
68 | +(shareSuccess)shareSuccessCallback{
69 | return shareSuccessCallback;
70 | }
71 | +(shareFail)shareFailCallback{
72 | return shareFailCallback;
73 | }
74 | +(void)setShareSuccessCallback:(shareSuccess)suc{
75 | shareSuccessCallback=suc;
76 | }
77 | +(void)setShareFailCallback:(shareFail)fail{
78 | shareFailCallback=fail;
79 | }
80 | +(void)setPaySuccessCallback:(paySuccess)suc{
81 | paySuccessCallback=suc;
82 | }
83 | +(void)setPayFailCallback:(payFail)fail{
84 | payFailCallback=fail;
85 | }
86 | +(paySuccess)paySuccessCallback{
87 | return paySuccessCallback;
88 | }
89 | +(payFail)payFailCallback{
90 | return payFailCallback;
91 | }
92 | +(NSURL*)returnedURL{
93 | return returnedURL;
94 | }
95 | +(NSDictionary*)returnedData{
96 | return returnedData;
97 | }
98 | +(void)setReturnedData:(NSDictionary*)retData{
99 | returnedData=retData;
100 | }
101 | +(void)setMessage:(OSMessage*)msg{
102 | message=msg;
103 | }
104 | +(OSMessage*)message{
105 | return message?:[[OSMessage alloc] init];
106 | }
107 | +(authSuccess)authSuccessCallback{
108 | return authSuccessCallback;
109 | }
110 | +(authFail)authFailCallback{
111 | return authFailCallback;
112 | }
113 | +(BOOL)beginShare:(NSString*)platform Message:(OSMessage*)msg Success:(shareSuccess)success Fail:(shareFail)fail{
114 | if ([self keyFor:platform]) {
115 | message=msg;
116 | shareSuccessCallback=success;
117 | shareFailCallback=fail;
118 | return YES;
119 | }else{
120 | NSLog(@"please connect%@ before you can share to it!!!",platform);
121 | return NO;
122 | }
123 | }
124 | +(BOOL)beginAuth:(NSString*)platform Success:(authSuccess)success Fail:(authFail)fail{
125 | if ([self keyFor:platform]) {
126 | authSuccessCallback=success;
127 | authFailCallback=fail;
128 | return YES;
129 | }else{
130 | NSLog(@"please connect%@ before you can share to it!!!",platform);
131 | return NO;
132 | }
133 | }
134 |
135 | #pragma mark 公共实用方法
136 | +(NSMutableDictionary *)parseUrl:(NSURL*)url{
137 | NSMutableDictionary *queryStringDictionary = [[NSMutableDictionary alloc] init];
138 | NSArray *urlComponents = [[url query] componentsSeparatedByString:@"&"];
139 |
140 | for (NSString *keyValuePair in urlComponents)
141 | {
142 | NSRange range=[keyValuePair rangeOfString:@"="];
143 | [queryStringDictionary setObject:range.length>0?[keyValuePair substringFromIndex:range.location+1]:@"" forKey:(range.length?[keyValuePair substringToIndex:range.location]:keyValuePair)];
144 | }
145 | return queryStringDictionary;
146 | }
147 | +(NSString*)base64Encode:(NSString *)input{
148 | return [[input dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
149 | }
150 | +(NSString*)base64Decode:(NSString *)input{
151 | return [[NSString alloc ] initWithData:[[NSData alloc] initWithBase64EncodedString:input options:0] encoding:NSUTF8StringEncoding];
152 | }
153 | +(NSString*)CFBundleDisplayName{
154 | return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
155 | }
156 | +(NSString*)CFBundleIdentifier{
157 | return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
158 | }
159 | +(void)setGeneralPasteboard:(NSString*)key Value:(NSDictionary*)value encoding:(OSPboardEncoding)encoding{
160 | if (value&&key) {
161 | NSData *data=nil;
162 | NSError *err;
163 | switch (encoding) {
164 | case OSPboardEncodingKeyedArchiver:
165 | data=[NSKeyedArchiver archivedDataWithRootObject:value];
166 | break;
167 | case OSPboardEncodingPropertyListSerialization:
168 | data=[NSPropertyListSerialization dataWithPropertyList:value format:NSPropertyListBinaryFormat_v1_0 options:0 error:&err];
169 | default:
170 | NSLog(@"encoding not implemented");
171 | break;
172 | }
173 | if (err) {
174 | NSLog(@"error when NSPropertyListSerialization: %@",err);
175 | }else if (data){
176 | [[UIPasteboard generalPasteboard] setData:data forPasteboardType:key];
177 | }
178 | }
179 | }
180 | +(NSDictionary*)generalPasteboardData:(NSString*)key encoding:(OSPboardEncoding)encoding{
181 | NSData *data=[[UIPasteboard generalPasteboard] dataForPasteboardType:key];
182 | NSDictionary *dic=nil;
183 | if (data) {
184 | NSError *err;
185 | switch (encoding) {
186 | case OSPboardEncodingKeyedArchiver:
187 | dic= [NSKeyedUnarchiver unarchiveObjectWithData:data];
188 | break;
189 | case OSPboardEncodingPropertyListSerialization:
190 | dic=[NSPropertyListSerialization propertyListWithData:data options:0 format:0 error:&err];
191 | default:
192 | break;
193 | }
194 | if (err) {
195 | NSLog(@"error when NSPropertyListSerialization: %@",err);
196 | }
197 | }
198 | return dic;
199 | }
200 | +(NSString*)base64AndUrlEncode:(NSString *)string{
201 | return [[self base64Encode:string] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
202 | }
203 | +(NSString*)urlDecode:(NSString*)input{
204 | return [[input stringByReplacingOccurrencesOfString:@"+" withString:@" "]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
205 | }
206 | /**
207 | * 截屏功能。via:http://stackoverflow.com/a/8017292/3825920
208 | *
209 | * @return 对当前窗口截屏。(支付宝可能需要)
210 | */
211 | + (UIImage *)screenshot
212 | {
213 | CGSize imageSize = CGSizeZero;
214 |
215 | UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
216 | if (UIInterfaceOrientationIsPortrait(orientation)) {
217 | imageSize = [UIScreen mainScreen].bounds.size;
218 | } else {
219 | imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
220 | }
221 |
222 | UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
223 | CGContextRef context = UIGraphicsGetCurrentContext();
224 | for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
225 | CGContextSaveGState(context);
226 | CGContextTranslateCTM(context, window.center.x, window.center.y);
227 | CGContextConcatCTM(context, window.transform);
228 | CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
229 | if (orientation == UIInterfaceOrientationLandscapeLeft) {
230 | CGContextRotateCTM(context, M_PI_2);
231 | CGContextTranslateCTM(context, 0, -imageSize.width);
232 | } else if (orientation == UIInterfaceOrientationLandscapeRight) {
233 | CGContextRotateCTM(context, -M_PI_2);
234 | CGContextTranslateCTM(context, -imageSize.height, 0);
235 | } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
236 | CGContextRotateCTM(context, M_PI);
237 | CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
238 | }
239 | if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
240 | [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
241 | } else {
242 | [window.layer renderInContext:context];
243 | }
244 | CGContextRestoreGState(context);
245 | }
246 |
247 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
248 | UIGraphicsEndImageContext();
249 | return image;
250 | }
251 |
252 | + (NSData *)dataWithImage:(UIImage *)image {
253 | return UIImageJPEGRepresentation(image, 1);
254 | }
255 |
256 | + (NSData *)dataWithImage:(UIImage *)image scale:(CGSize)size {
257 | UIGraphicsBeginImageContext(size);
258 | [image drawInRect:CGRectMake(0,0, size.width, size.height)];
259 | UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
260 | UIGraphicsEndImageContext();
261 | return UIImageJPEGRepresentation(scaledImage, 1);
262 | }
263 |
264 | - (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size{
265 | UIGraphicsBeginImageContext(size);
266 | [image drawInRect:CGRectMake(0,0, size.width, size.height)];
267 | UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
268 | UIGraphicsEndImageContext();
269 | return scaledImage;
270 | }
271 |
272 | @end
273 |
274 | @implementation OSMessage
275 | -(BOOL)isEmpty:(NSArray*)emptyValueForKeys AndNotEmpty:(NSArray*)notEmptyValueForKeys{
276 | @try {
277 | if (emptyValueForKeys) {
278 | for (NSString *key in emptyValueForKeys) {
279 | if ([self valueForKeyPath:key]) {
280 | return NO;
281 | }
282 | }
283 | }
284 | if (notEmptyValueForKeys) {
285 | for (NSString *key in notEmptyValueForKeys) {
286 | if (![self valueForKey:key]) {
287 | return NO;
288 | }
289 | }
290 | }
291 | return YES;
292 | }
293 | @catch (NSException *exception) {
294 | NSLog(@"isEmpty error:\n %@",exception);
295 | return NO;
296 | }
297 | }
298 |
299 | @end
300 |
--------------------------------------------------------------------------------