README.md
30.4 KB
低版本ReactNative在XCode11启动时异常问题的解决方案,需要修改RCTModuleMethod.m文件,具体见https://blog.csdn.net/lizhijian21/article/details/101367768,修改方法如下 static BOOL RCTParseUnused(const char **input) {
return RCTReadString(input, "__unused") ||
RCTReadString(input, "__attribute__((__unused__))") || //Xcode11 fix,https://blog.csdn.net/lizhijian21/article/details/101367768
RCTReadString(input, "__attribute__((unused))");
}
ios13适配 react-native的RCTWebView.m,由基于uiwebview的实现改为了基于wkwebivew的实现 以下是修改后的RCTWebView.m文件
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTWebView.h"
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import "RCTAutoInsetsProtocol.h"
#import "RCTConvert.h"
#import "RCTEventDispatcher.h"
#import "RCTLog.h"
#import "RCTUtils.h"
#import "RCTView.h"
#import "UIView+React.h"
NSString *const RCTJSNavigationScheme = @"react-js-navigation";
NSString *const RCTJSPostMessageHost = @"postMessage";
@interface RCTWebView () <WKNavigationDelegate, RCTAutoInsetsProtocol>
@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest;
@property (nonatomic, copy) RCTDirectEventBlock onMessage;
@end
@implementation RCTWebView
{
WKWebView *_webView;
NSString *_injectedJavaScript;
BOOL _scalesPageToFit;// wkwebview没有scalesPageToFit属性了,这里用本地变量来保存
}
- (void)dealloc
{
_webView.navigationDelegate = nil;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
super.backgroundColor = [UIColor clearColor];
_automaticallyAdjustContentInsets = YES;
_contentInset = UIEdgeInsetsZero;
_webView = [[WKWebView alloc] initWithFrame:self.bounds];
// 用来适配设备宽度,阻止用户自行捏合缩放页面(REQ2021022000015+REQ2021022200003)
NSString *jsToScaleFit = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width');meta.setAttribute('user-scalable', 'no'); document.getElementsByTagName('head')[0].appendChild(meta);";
// 注意注入的时间,是WKUserScriptInjectionTimeAtDocumentEnd!!!
WKUserScript *userScript = [[WKUserScript alloc] initWithSource:jsToScaleFit injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
WKWebViewConfiguration *userConfig = [[WKWebViewConfiguration alloc]init];
// FIXME:无效???
// // 创建设置对象
// WKPreferences *preference = [[WKPreferences alloc]init];
// // 设置字体大小(最小的字体大小)
// preference.minimumFontSize = 100;
// // 设置偏好设置对象
// userConfig.preferences = preference;
WKUserContentController *userController = [[WKUserContentController alloc]init];
[userController addUserScript:userScript];
[userConfig setUserContentController:userController];
_webView = [[WKWebView alloc] initWithFrame:self.bounds configuration:userConfig];
_webView.navigationDelegate = self;
[self addSubview:_webView];
}
return self;
}
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (void)goForward
{
[_webView goForward];
}
- (void)goBack
{
[_webView goBack];
}
- (void)reload
{
NSURLRequest *request = [RCTConvert NSURLRequest:self.source];
if (request.URL && !_webView.URL.absoluteString.length) {
[_webView loadRequest:request];
}
else {
[_webView reload];
}
}
- (void)stopLoading
{
[_webView stopLoading];
}
- (void)postMessage:(NSString *)message
{
NSDictionary *eventInitDict = @{
@"data": message,
};
NSString * source = [NSString
stringWithFormat:@"document.dispatchEvent(new MessageEvent('message', %@));",
RCTJSONStringify(eventInitDict, NULL)
];
[_webView evaluateJavaScript:source completionHandler:nil];
}
- (void)injectJavaScript:(NSString *)script
{
[_webView evaluateJavaScript:script completionHandler:nil];
}
- (void)setSource:(NSDictionary *)source
{
if (![_source isEqualToDictionary:source]) {
_source = [source copy];
// Check for a static html source first
NSString *html = [RCTConvert NSString:source[@"html"]];
if (html) {
NSURL *baseURL = [RCTConvert NSURL:source[@"baseUrl"]];
if (!baseURL) {
baseURL = [NSURL URLWithString:@"about:blank"];
}
[_webView loadHTMLString:html baseURL:baseURL];
return;
}
NSURLRequest *request = [RCTConvert NSURLRequest:source];
// Because of the way React works, as pages redirect, we actually end up
// passing the redirect urls back here, so we ignore them if trying to load
// the same url. We'll expose a call to 'reload' to allow a user to load
// the existing page.
if ([request.URL isEqual:_webView.URL]) {
return;
}
if (!request.URL) {
// Clear the webview
[_webView loadHTMLString:@"" baseURL:nil];
return;
}
[_webView loadRequest:request];
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
_webView.frame = self.bounds;
}
- (void)setContentInset:(UIEdgeInsets)contentInset
{
_contentInset = contentInset;
[RCTView autoAdjustInsetsForView:self
withScrollView:_webView.scrollView
updateOffset:NO];
}
- (void)setScalesPageToFit:(BOOL)scalesPageToFit
{
// if (_webView.scalesPageToFit != scalesPageToFit) {
// _webView.scalesPageToFit = scalesPageToFit;
// [_webView reload];
// }
if(_scalesPageToFit != scalesPageToFit){
_scalesPageToFit = scalesPageToFit;
[_webView reload];
}
}
- (BOOL)scalesPageToFit
{
// return _webView.scalesPageToFit;
return _scalesPageToFit;
}
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor);
self.opaque = _webView.opaque = (alpha == 1.0);
_webView.backgroundColor = backgroundColor;
}
- (UIColor *)backgroundColor
{
return _webView.backgroundColor;
}
- (NSMutableDictionary<NSString *, id> *)baseEvent
{
// @"title": [_webView stringByEvaluatingJavaScriptFromString:@"document.title"],
NSMutableDictionary<NSString *, id> *event = [[NSMutableDictionary alloc] initWithDictionary:@{
@"url": _webView.URL.absoluteString ?: @"",
@"loading" : @(_webView.loading),
@"title": @"",
@"canGoBack": @(_webView.canGoBack),
@"canGoForward" : @(_webView.canGoForward),
}];
return event;
}
- (void)refreshContentInset
{
[RCTView autoAdjustInsetsForView:self
withScrollView:_webView.scrollView
updateOffset:YES];
}
#pragma mark -WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
// 允许全部跳转请求,报错处理已经在WKJavaScriptBridge中被截胡了
// 如果是跳转一个新页面,发送请求
// if (navigationAction.targetFrame == nil) {
// [webView loadRequest:navigationAction.request];
// }
BOOL isJSNavigation = [navigationAction.request.URL.scheme isEqualToString:RCTJSNavigationScheme];
static NSDictionary<NSNumber *, NSString *> *navigationTypes;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
navigationTypes = @{
@(WKNavigationTypeLinkActivated): @"click",
@(WKNavigationTypeFormSubmitted): @"formsubmit",
@(WKNavigationTypeBackForward): @"backforward",
@(WKNavigationTypeReload): @"reload",
@(WKNavigationTypeFormResubmitted): @"formresubmit",
@(WKNavigationTypeOther): @"other",
};
});
// skip this for the JS Navigation handler
if (!isJSNavigation && _onShouldStartLoadWithRequest) {
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary: @{
@"url": (navigationAction.request.URL).absoluteString,
@"navigationType": navigationTypes[@(navigationAction.navigationType)]
}];
if (![self.delegate webView:self
shouldStartLoadForRequest:event
withCallback:_onShouldStartLoadWithRequest]) {
return decisionHandler(WKNavigationActionPolicyCancel);
}
}
if (_onLoadingStart) {
// We have this check to filter out iframe requests and whatnot
BOOL isTopFrame = [navigationAction.request.URL isEqual:navigationAction.request.mainDocumentURL];
if (isTopFrame) {
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary: @{
@"url": (navigationAction.request.URL).absoluteString,
@"navigationType": navigationTypes[@(navigationAction.navigationType)]
}];
_onLoadingStart(event);
}
}
if (isJSNavigation && [navigationAction.request.URL.host isEqualToString:RCTJSPostMessageHost]) {
NSString *data = navigationAction.request.URL.query;
data = [data stringByReplacingOccurrencesOfString:@"+" withString:@" "];
data = [data stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary: @{
@"data": data,
}];
_onMessage(event);
}
// JS Navigation handler
// return !isJSNavigation;
if(!isJSNavigation){
decisionHandler(WKNavigationActionPolicyAllow);
}else{
decisionHandler(WKNavigationActionPolicyCancel);
}
}
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation
{
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
if (_messagingEnabled) {
#if RCT_DEV
// See isNative in lodash
NSString *testPostMessageNative = @"String(window.postMessage) === String(Object.hasOwnProperty).replace('hasOwnProperty', 'postMessage')";
// BOOL postMessageIsNative = [
// [webView stringByEvaluatingJavaScriptFromString:testPostMessageNative]
// isEqualToString:@"true"
// ];
// if (!postMessageIsNative) {
// RCTLogError(@"Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
// }
[webView evaluateJavaScript:testPostMessageNative completionHandler:^(id _Nullable value, NSError * _Nullable error) {
if(error){
RCTLogError(@"Setting onMessage on a WebView overrides existing values of window.postMessage, but a previous value was defined");
}
}];
#endif
NSString *source = [NSString stringWithFormat:
@"window.originalPostMessage = window.postMessage;"
"window.postMessage = function(data) {"
"window.location = '%@://%@?' + encodeURIComponent(String(data));"
"};", RCTJSNavigationScheme, RCTJSPostMessageHost
];
[webView evaluateJavaScript:source completionHandler:nil];
}
if (_injectedJavaScript != nil) {
// 根据注入的方法名来判断是否需要获取webview内容高度
if([_injectedJavaScript containsString:@"function changeHeight()"]){
[webView evaluateJavaScript:@"document.body.offsetHeight"
completionHandler:^(id _Nullableresult,NSError*_Nullableerror) {
CGFloat web_h = webView.scrollView.contentSize.height;
// 高度比较,取最大值
if(_Nullableresult && [_Nullableresult isKindOfClass:[NSNumber class]]){
CGFloat _height = [(NSNumber *)_Nullableresult floatValue];
if (_height > web_h) {
web_h = _height;
}
}
//设置webView高度
CGRect supframe = webView.frame;
supframe.size.height = web_h;
webView.frame = supframe;
[webView evaluateJavaScript:_injectedJavaScript completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSString *jsEvaluationValue = (NSString *)result;
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
event[@"jsEvaluationValue"] = jsEvaluationValue;
_onLoadingFinish(event);
}];
}];
}else{
[webView evaluateJavaScript:_injectedJavaScript completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSString *jsEvaluationValue = (NSString *)result;
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
event[@"jsEvaluationValue"] = jsEvaluationValue;
_onLoadingFinish(event);
}];
}
if(![_injectedJavaScript containsString:@"type: 'setHeight',"] && ![_injectedJavaScript containsString:@"setInterval(changeHeight, 100);"]){
[webView evaluateJavaScript:_injectedJavaScript completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSString *jsEvaluationValue = (NSString *)result;
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
event[@"jsEvaluationValue"] = jsEvaluationValue;
_onLoadingFinish(event);
}];
}
// NSString *jsEvaluationValue = [webView stringByEvaluatingJavaScriptFromString:_injectedJavaScript];
// NSMutableDictionary<NSString *, id> *event = [self baseEvent];
// event[@"jsEvaluationValue"] = jsEvaluationValue;
// _onLoadingFinish(event);
}
// we only need the final 'finishLoad' call so only fire the event when we're actually done loading.
else if (_onLoadingFinish && !webView.loading && ![webView.URL.absoluteString isEqualToString:@"about:blank"]) {
_onLoadingFinish([self baseEvent]);
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
{
if (_onLoadingError) {
if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) {
// NSURLErrorCancelled is reported when a page has a redirect OR if you load
// a new URL in the WebView before the previous one came back. We can just
// ignore these since they aren't real errors.
// http://stackoverflow.com/questions/1024748/how-do-i-fix-nsurlerrordomain-error-999-in-iphone-3-0-os
return;
}
if ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102) {
// Error code 102 "Frame load interrupted" is raised by the if
// its delegate returns FALSE from webView:shouldStartLoadWithRequest:navigationType
// when the URL is from an http redirect. This is a common pattern when
// implementing OAuth with a WebView.
return;
}
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
[event addEntriesFromDictionary:@{
@"domain": error.domain,
@"code": @(error.code),
@"description": error.localizedDescription,
}];
_onLoadingError(event);
}
}
@end
RCTWechat因为友盟已经依赖了wechatSDK,所以就把RN的依赖去除了,仅保留RCTWeChat.h和RCTWechat.m,且修改了 RCTWeChat.m的源码用来适配新的WechatSDK,但注意目前universalLink没有设置!!!会导致分享无效,另外企信没有接入react-native-wechat,这里记录仅仅记录一下防止后面万一接入了出问题
//
// RCTWeChat.m
// RCTWeChat
//
// Created by Yorkie Liu on 10/16/15.
// Copyright © 2015 WeFlex. All rights reserved.
//
#import "RCTWeChat.h"
#import "WXApiObject.h"
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridge.h>
#import <React/RCTLog.h>
#import <React/RCTImageLoader.h>
// Define error messages
#define NOT_REGISTERED (@"registerApp required.")
#define INVOKE_FAILED (@"WeChat API invoke returns false.")
@implementation RCTWeChat
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE(WeChat)
- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:@"RCTOpenURLNotification" object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (BOOL)handleOpenURL:(NSNotification *)aNotification
{
NSString * aURLString = [aNotification userInfo][@"url"];
NSURL * aURL = [NSURL URLWithString:aURLString];
if ([WXApi handleOpenURL:aURL delegate:self])
{
return YES;
} else {
return NO;
}
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_METHOD(registerApp:(NSString *)appid
:(RCTResponseSenderBlock)callback)
{
self.appId = appid;
callback(@[[WXApi registerApp:appid universalLink:@""] ? [NSNull null] : INVOKE_FAILED] );
}
RCT_EXPORT_METHOD(registerAppWithDescription:(NSString *)appid
:(NSString *)appdesc
:(RCTResponseSenderBlock)callback)
{
callback(@[[WXApi registerApp:appid universalLink:@""] ? [NSNull null] : INVOKE_FAILED]);
}
RCT_EXPORT_METHOD(isWXAppInstalled:(RCTResponseSenderBlock)callback)
{
callback(@[[NSNull null], @([WXApi isWXAppInstalled])]);
}
RCT_EXPORT_METHOD(isWXAppSupportApi:(RCTResponseSenderBlock)callback)
{
callback(@[[NSNull null], @([WXApi isWXAppSupportApi])]);
}
RCT_EXPORT_METHOD(getWXAppInstallUrl:(RCTResponseSenderBlock)callback)
{
callback(@[[NSNull null], [WXApi getWXAppInstallUrl]]);
}
RCT_EXPORT_METHOD(getApiVersion:(RCTResponseSenderBlock)callback)
{
callback(@[[NSNull null], [WXApi getApiVersion]]);
}
RCT_EXPORT_METHOD(openWXApp:(RCTResponseSenderBlock)callback)
{
callback(@[([WXApi openWXApp] ? [NSNull null] : INVOKE_FAILED)]);
}
RCT_EXPORT_METHOD(sendRequest:(NSString *)openid
:(RCTResponseSenderBlock)callback)
{
BaseReq* req = [[BaseReq alloc] init];
req.openID = openid;
[WXApi sendReq:req completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
RCT_EXPORT_METHOD(sendAuthRequest:(NSString *)scope
:(NSString *)state
:(RCTResponseSenderBlock)callback)
{
SendAuthReq* req = [[SendAuthReq alloc] init];
req.scope = scope;
req.state = state;
[WXApi sendReq:req completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
RCT_EXPORT_METHOD(sendSuccessResponse:(RCTResponseSenderBlock)callback)
{
BaseResp* resp = [[BaseResp alloc] init];
resp.errCode = WXSuccess;
[WXApi sendResp:resp completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
RCT_EXPORT_METHOD(sendErrorCommonResponse:(NSString *)message
:(RCTResponseSenderBlock)callback)
{
BaseResp* resp = [[BaseResp alloc] init];
resp.errCode = WXErrCodeCommon;
resp.errStr = message;
[WXApi sendResp:resp completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
RCT_EXPORT_METHOD(sendErrorUserCancelResponse:(NSString *)message
:(RCTResponseSenderBlock)callback)
{
BaseResp* resp = [[BaseResp alloc] init];
resp.errCode = WXErrCodeUserCancel;
resp.errStr = message;
[WXApi sendResp:resp completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
RCT_EXPORT_METHOD(shareToTimeline:(NSDictionary *)data
:(RCTResponseSenderBlock)callback)
{
[self shareToWeixinWithData:data scene:WXSceneTimeline callback:callback];
}
RCT_EXPORT_METHOD(shareToSession:(NSDictionary *)data
:(RCTResponseSenderBlock)callback)
{
[self shareToWeixinWithData:data scene:WXSceneSession callback:callback];
}
RCT_EXPORT_METHOD(pay:(NSDictionary *)data
:(RCTResponseSenderBlock)callback)
{
PayReq* req = [PayReq new];
req.partnerId = data[@"partnerId"];
req.prepayId = data[@"prepayId"];
req.nonceStr = data[@"nonceStr"];
req.timeStamp = [data[@"timeStamp"] unsignedIntValue];
req.package = data[@"package"];
req.sign = data[@"sign"];
[WXApi sendReq:req completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
- (void)shareToWeixinWithData:(NSDictionary *)aData
thumbImage:(UIImage *)aThumbImage
scene:(int)aScene
callBack:(RCTResponseSenderBlock)callback
{
NSString *type = aData[RCTWXShareType];
if ([type isEqualToString:RCTWXShareTypeText]) {
NSString *text = aData[RCTWXShareDescription];
[self shareToWeixinWithTextMessage:aScene Text:text callBack:callback];
} else {
NSString * title = aData[RCTWXShareTitle];
NSString * description = aData[RCTWXShareDescription];
NSString * mediaTagName = aData[@"mediaTagName"];
NSString * messageAction = aData[@"messageAction"];
NSString * messageExt = aData[@"messageExt"];
if (type.length <= 0 || [type isEqualToString:RCTWXShareTypeNews]) {
NSString * webpageUrl = aData[RCTWXShareWebpageUrl];
if (webpageUrl.length <= 0) {
callback(@[@"webpageUrl required"]);
return;
}
WXWebpageObject* webpageObject = [WXWebpageObject object];
webpageObject.webpageUrl = webpageUrl;
[self shareToWeixinWithMediaMessage:aScene
title:title
Description:description
Object:webpageObject
MessageExt:messageExt
MessageAction:messageAction
ThumbImage:aThumbImage
MediaTag:mediaTagName
callBack:callback];
} else if ([type isEqualToString:RCTWXShareTypeAudio]) {
WXMusicObject *musicObject = [WXMusicObject new];
musicObject.musicUrl = aData[@"musicUrl"];
musicObject.musicLowBandUrl = aData[@"musicLowBandUrl"];
musicObject.musicDataUrl = aData[@"musicDataUrl"];
musicObject.musicLowBandDataUrl = aData[@"musicLowBandDataUrl"];
[self shareToWeixinWithMediaMessage:aScene
title:title
Description:description
Object:musicObject
MessageExt:messageExt
MessageAction:messageAction
ThumbImage:aThumbImage
MediaTag:mediaTagName
callBack:callback];
} else if ([type isEqualToString:RCTWXShareTypeVideo]) {
WXVideoObject *videoObject = [WXVideoObject new];
videoObject.videoUrl = aData[@"videoUrl"];
videoObject.videoLowBandUrl = aData[@"videoLowBandUrl"];
[self shareToWeixinWithMediaMessage:aScene
title:title
Description:description
Object:videoObject
MessageExt:messageExt
MessageAction:messageAction
ThumbImage:aThumbImage
MediaTag:mediaTagName
callBack:callback];
} else if ([type isEqualToString:RCTWXShareTypeImageUrl] ||
[type isEqualToString:RCTWXShareTypeImageFile] ||
[type isEqualToString:RCTWXShareTypeImageResource]) {
NSURL *url = [NSURL URLWithString:aData[RCTWXShareImageUrl]];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url];
[self.bridge.imageLoader loadImageWithURLRequest:imageRequest callback:^(NSError *error, UIImage *image) {
if (image == nil){
callback(@[@"fail to load image resource"]);
} else {
WXImageObject *imageObject = [WXImageObject object];
imageObject.imageData = UIImagePNGRepresentation(image);
[self shareToWeixinWithMediaMessage:aScene
title:title
Description:description
Object:imageObject
MessageExt:messageExt
MessageAction:messageAction
ThumbImage:aThumbImage
MediaTag:mediaTagName
callBack:callback];
}
}];
} else if ([type isEqualToString:RCTWXShareTypeFile]) {
NSString * filePath = aData[@"filePath"];
NSString * fileExtension = aData[@"fileExtension"];
WXFileObject *fileObject = [WXFileObject object];
fileObject.fileData = [NSData dataWithContentsOfFile:filePath];
fileObject.fileExtension = fileExtension;
[self shareToWeixinWithMediaMessage:aScene
title:title
Description:description
Object:fileObject
MessageExt:messageExt
MessageAction:messageAction
ThumbImage:aThumbImage
MediaTag:mediaTagName
callBack:callback];
} else {
callback(@[@"message type unsupported"]);
}
}
}
- (void)shareToWeixinWithData:(NSDictionary *)aData scene:(int)aScene callback:(RCTResponseSenderBlock)aCallBack
{
NSString *imageUrl = aData[RCTWXShareTypeThumbImageUrl];
if (imageUrl.length && _bridge.imageLoader) {
NSURL *url = [NSURL URLWithString:imageUrl];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:url];
[_bridge.imageLoader loadImageWithURLRequest:imageRequest size:CGSizeMake(100, 100) scale:1 clipped:FALSE resizeMode:RCTResizeModeStretch progressBlock:nil partialLoadBlock:nil
completionBlock:^(NSError *error, UIImage *image) {
[self shareToWeixinWithData:aData thumbImage:image scene:aScene callBack:aCallBack];
}];
} else {
[self shareToWeixinWithData:aData thumbImage:nil scene:aScene callBack:aCallBack];
}
}
- (void)shareToWeixinWithTextMessage:(int)aScene
Text:(NSString *)text
callBack:(RCTResponseSenderBlock)callback
{
SendMessageToWXReq* req = [SendMessageToWXReq new];
req.bText = YES;
req.scene = aScene;
req.text = text;
[WXApi sendReq:req completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
- (void)shareToWeixinWithMediaMessage:(int)aScene
title:(NSString *)title
Description:(NSString *)description
Object:(id)mediaObject
MessageExt:(NSString *)messageExt
MessageAction:(NSString *)action
ThumbImage:(UIImage *)thumbImage
MediaTag:(NSString *)tagName
callBack:(RCTResponseSenderBlock)callback
{
WXMediaMessage *message = [WXMediaMessage message];
message.title = title;
message.description = description;
message.mediaObject = mediaObject;
message.messageExt = messageExt;
message.messageAction = action;
message.mediaTagName = tagName;
[message setThumbImage:thumbImage];
SendMessageToWXReq* req = [SendMessageToWXReq new];
req.bText = NO;
req.scene = aScene;
req.message = message;
[WXApi sendReq:req completion:^(BOOL success) {
if(success){
callback(@[[NSNull null]]);
}else{
callback(@[INVOKE_FAILED]);
}
}];
}
#pragma mark - wx callback
-(void) onReq:(BaseReq*)req
{
// TODO(Yorkie)
}
-(void) onResp:(BaseResp*)resp
{
if([resp isKindOfClass:[SendMessageToWXResp class]])
{
SendMessageToWXResp *r = (SendMessageToWXResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
body[@"errStr"] = r.errStr;
body[@"lang"] = r.lang;
body[@"country"] =r.country;
body[@"type"] = @"SendMessageToWX.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
} else if ([resp isKindOfClass:[SendAuthResp class]]) {
SendAuthResp *r = (SendAuthResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
body[@"errStr"] = r.errStr;
body[@"state"] = r.state;
body[@"lang"] = r.lang;
body[@"country"] =r.country;
body[@"type"] = @"SendAuth.Resp";
if (resp.errCode == WXSuccess)
{
[body addEntriesFromDictionary:@{@"appid":self.appId, @"code" :r.code}];
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
}
else {
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
}
} else if ([resp isKindOfClass:[PayResp class]]) {
PayResp *r = (PayResp *)resp;
NSMutableDictionary *body = @{@"errCode":@(r.errCode)}.mutableCopy;
body[@"errStr"] = r.errStr;
body[@"type"] = @(r.type);
body[@"returnKey"] =r.returnKey;
body[@"type"] = @"PayReq.Resp";
[self.bridge.eventDispatcher sendDeviceEventWithName:RCTWXEventName body:body];
}
}
@end