集成 MPWeex 到 iOS
使用CocoaPods可以方便的将MPWeex集成到自己的项目中, 也可以手动将MPWeex集成到自己的项目中。
1. CocoaPods
从CocoaPods仓库中获取MPWeex的最新版本。
将MPWeex依赖添加到你的Podfile文件中:
source 'git@github.com:CocoaPods/Specs.git'
target 'YourTarget' do
platform :ios, '8.0'
pod 'MPWeexSDK', '0.28.0'
end
运行 pod install
命令安装依赖。
2. 手动集成
从GitHub仓库中获取MPWeex的最新版本。
将MPWeexSDK文件夹添加到你的项目中。
将libc++
、libiconv
、libresolv
、libz
库添加到你的项目中。
将CoreServices
, AVFoundation
, AVKit
, CoreMedia
, CoreTelephony
, GLKit
, JavaScriptCore
, MediaPlayer
, Security
, SystemConfiguration
, WebKit
框架添加到你的项目中。
将第三方库依赖添加到你的Podfile文件中:
source 'git@github.com:CocoaPods/Specs.git'
target 'YourTarget' do
platform :ios, '8.0'
pod 'GZIP', '~> 1.2'
pod 'SSZipArchive'
pod 'AliyunOSSiOS'
pod 'YYModel'
pod 'yismcore', '~> 0.1.0'
end
运行 pod install
命令安装依赖。
3. 初始化SDK
APP商户入驻成功后,系统会分配APPID、License和白盒密码算法密钥mpweex.bmp,将mpweex.bmp添加到工程目录中。
建议在 didFinishLaunchingWithOptions
回调中初始化MPWeex。
// 初始化MPWeex
[[MPWeexSDKManager sharedInstance] initialize];
[[MPWeexSDKManager sharedInstance] setAppID:@"your mpweex appid."
license:@"your mpweex license."];
[[MPWeexSDKManager sharedInstance] setBasePath:@"mpweex api host."];
4. 扩展图片加载
MPWeex不提供图片加载能力。自定义图片加载,需要实现WXImgLoaderProtocol协议。
#import "WXImageProtocolImpl.h"
#import <MPWeexSDK/WXUtility.h>
#import <YYWebImage/YYWebImageManager.h>
@implementation WXImageProtocolImpl
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url
imageFrame:(CGRect)imageFrame
userInfo:(NSDictionary *)options
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock {
if ([WXUtility isBlankString:url]) {
return nil;
}
if (!completedBlock) {
return nil;
}
// 正则表达式匹配base64图片
NSArray *matchesResults = [self matchesBase64Image:url];
if (matchesResults && matchesResults.count > 0) {
NSTextCheckingResult *matchesResult = matchesResults.firstObject;
NSString *type = [url substringWithRange:[matchesResult rangeAtIndex:2]];
NSString *imageBaseCode = [url substringWithRange:[matchesResult rangeAtIndex:3]];
// base64 image
if ([type isEqualToString:@"base64"] && ![WXUtility isBlankString:imageBaseCode]) {
[self loadBase64ImageWithImageBaseCode:imageBaseCode completed:completedBlock];
}
} else {
if ([url hasPrefix:@"//"]) {
// ordinary network image
[self loadImageWithUrl:[NSString stringWithFormat:@"http:%@", url] completed:completedBlock];
} else {
if ([[NSURL URLWithString:url].scheme isEqualToString:@"file"]) {
// local image
NSString *imagePath = [url stringByReplacingOccurrencesOfString:@"file:///" withString:@""];
[self loadLocalImageWithFilePath:imagePath completed:completedBlock];
} else {
// oss image
[self loadOSSImageWithUrl:url completed:completedBlock];
}
}
}
return nil;
}
- (NSArray *)matchesBase64Image:(NSString *)url {
NSString *pattern = @"^data:image/(.*?);(.*?),(.*)$";
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:NULL];
return [regularExpression matchesInString:url
options:NSMatchingReportCompletion
range:NSMakeRange(0, url.length)];
}
- (void)loadImageWithUrl:(NSString *)url
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock {
[[YYWebImageManager sharedManager] requestImageWithURL:[NSURL URLWithString:url]
options:YYWebImageOptionSetImageWithFadeAnimation
progress:nil
transform:nil
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) {
if (!error && image) {
completedBlock(image, nil, YES);
} else {
completedBlock(nil, [self errorWithDescription:@"load image failed."], YES);
}
}];
}
- (void)loadOSSImageWithUrl:(NSString *)url
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock {
[[YYWebImageManager sharedManager] requestImageWithURL:[NSURL URLWithString:url]
options:YYWebImageOptionSetImageWithFadeAnimation
progress:nil
transform:nil
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) {
if (!error && image) {
completedBlock(image, nil, YES);
} else {
completedBlock(nil, [self errorWithDescription:@"load oss image failed."], YES);
}
}];
}
- (void)loadBase64ImageWithImageBaseCode:(NSString *)imageBase64Code
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock {
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:imageBase64Code options:0];
UIImage *image = [UIImage imageWithData:imageData];
if (image) {
completedBlock(image, nil, YES);
} else {
completedBlock(nil, [self errorWithDescription:@"load base64 image failed."], YES);
}
}
- (void)loadLocalImageWithFilePath:(NSString *)filePath
completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock {
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
if (image) {
completedBlock(image, nil, YES);
} else {
completedBlock(nil, [self errorWithDescription:@"load local image failed."], YES);
}
} else {
completedBlock(nil, [self errorWithDescription:@"load local image failed, image file does not exist."], YES);
}
}
- (NSError *)errorWithDescription:(NSString *)errorDescription {
return [NSError errorWithDomain:WX_ERROR_DOMAIN
code:-1
userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
}
@end
4.1 修改初始化参数
// 初始化MPWeex
[[MPWeexSDKManager sharedInstance] initialize];
[[MPWeexSDKManager sharedInstance] setAppID:@"your mpweex appid."
license:@"your mpweex license."];
[[MPWeexSDKManager sharedInstance] setBasePath:@"mpweex api host."];
// 注册自定义图片加载协议实现
[[MPWeexSDKManager sharedInstance] registerHandler:[WXImageProtocolImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
5. 登录信息同步
APP内,如果要完全支持小程序功能,用户需要在小程序平台进行登录信息同步。在用户登录成功或用户资料有更新时,调用此接口。
TIP
此接口是幂等的,可重复调用,平台内只会进行一次用户信息登记。后续调用平台将会进行用户资料的同步操作。
接口描述
/// 登录成功后,将用户信息同步至小程序平台
/// @param platformUID APP商户应用的用户ID
/// @param phoneNo APP商户应用的用户手机号码
/// @param callback 回调
- (void)loginWithPlatformUID:(NSString *)platformUID
phoneNo:(NSString *)phoneNo
completionHandler:(WXOpenAccountCallback)callback;
DEMO
[[MPWeexSDKManager sharedInstance]
loginWithPlatformUID:@"your app useridentity"
phoneNo:@"your app user phone number"
completionHandler:^(BOOL sucessed, NSError *error) {
// your code if needed.
}];
6. 退出登录通知接口
APP内,如果退出登录了,需要调用此接口通知SDK,以进行登录状态的同步。
/// 退出登录时,通知SDK
- (void)logout;
DEMO
// 通知SDK退出登录
[[MPWeexSDKManager sharedInstance] logout];
7. 判断APP用户是否登录
因为大部分小程序都是需要用户登录后,才可以访问的,故需要APP实现IWXUserInfoAdapter告之小程序SDK,用户是否已登录成功。
TIP
主要实现ensureLogged,getUserInfo忽略
此适配器主要用于APP定制登录跳转或友好提示。
接口示例:
#import <UIKit/UIKit.h>
#import <MPWeexSDK/WXUserInfoProtocol.h>
@interface WXUserInfoProtocolImpl : NSObject <WXUserInfoProtocol>
/// 获取APP用户信息
- (WXUserInfoModel *)getUserInfo;
/// 确保用户已经登录
/// @param sourceViewController 源控制器
- (BOOL)ensureLoggedWithSourceViewController:(UIViewController *)sourceViewController;
@end
#import "WXUserInfoProtocolImpl.h"
#import <MPWeexSDK/WXUserInfoModel.h>
@implementation WXUserInfoProtocolImpl
- (WXUserInfoModel *)getUserInfo {
// deprecated, ignore it.
return nil;
}
// 用于判断APP用户是否已登录,请将方法内逻辑替换为APP判断用户是否已登录的逻辑。
- (BOOL)ensureLoggedWithSourceViewController:(UIViewController *)sourceViewController {
// APP用户登录状态
BOOL logined = YES;
if (logined) {
// 用户已登录则直接返回true
return true;
} else {
// 跳转实现
return false;
}
}
@end
- ensureLoggedWithSourceViewController: 此方法用于判断用户是否已经登录,因为大部分小程序都是需要用户登录后方可操作的。
7.1 修改初始化参数
// 初始化MPWeex
[[MPWeexSDKManager sharedInstance] initialize];
[[MPWeexSDKManager sharedInstance] setAppID:@"your mpweex appid."
license:@"your mpweex license."];
[[MPWeexSDKManager sharedInstance] setBasePath:@"mpweex api host."];
// 注册自定义用户协议实现
[[MPWeexSDKManager sharedInstance] registerHandler:[WXUserInfoProtocolImpl new] withProtocol:@protocol(WXUserInfoProtocol)];
8. SDK其它API使用方法
8.1 跳转至指定小程序
在APP中,可通过MPID跳转到指定的小程序。
- 接口
/// 跳转至小程序
/// @param sourceViewController 源控制器
/// @param mpID 小程序ID
/// @param logo 小程序图标
/// @param systemType 小程序系统类型 0宿主、1普通、 2游戏
/// @param offlineSupportType 是否支持离线访问 0不支持、1支持 不支持离线访问的,需要先登录
- (void)presentMPViewControllerWithSourceViewController:(UIViewController *)sourceViewController
mpID:(NSString *)mpID
logo:(NSString *)logo
systemType:(WXMPSystemType)systemType
offlineSupportType:(WXMPOfflineSupportType)offlineSupportType;
- 调用示例
[[MPWeexSDKManager sharedInstance] presentMPViewControllerWithSourceViewController:self
mpID:@"MPAAABa7vz87hIvbIAq1lG" // MPID
logo:@"images/AAFLlQAAAWzlpHpnAgI" // MP LOGO
systemType:WXMPSystemTypeNormal // MP TYPE 默认WXMPSystemTypeNormal
offlineSupportType:WXMPOfflineSupportTypeNotCan]; // 是否支持离线访问
8.2 跳转至指定页面
在APP中,可通过SDK跳转到指定的小程序页面。
- 接口
/// 跳转到指定页面
/// @param sourceViewController 源控制器
/// @param page 指定页面
- (void)presentMPPageWithSourceViewController:(UIViewController *)sourceViewController mpPage:(WXMPPage)page;
- 页面参数
typedef struct {
NSString *page;
NSString *pageTitle;
} WXMPPage;
static const WXMPPage kPageIndex = {@"/default.js", @"众圈"};
static const WXMPPage kPageRecent = {@"/pages/wxmp.js", @"最近使用"};
static const WXMPPage kPageMymp = {@"/pages/minemp.js", @"我关注的"};
static const WXMPPage kPageRecommend = {@"/pages/recommendmp.js", @"推荐的"};
static const WXMPPage kPageSearch = {@"/pages/search.js", @"搜索"};
- 调用示例
[[MPWeexSDKManager sharedInstance] presentMPPageWithSourceViewController:self
mpPage:kPageIndex];