1. 离线包就是个压缩包,有可能没有后缀,有可能后缀是.tar或.amr.但改成.zip后都可以解压出来源文件。如果人为更改了内容,再压缩回去是用不了的,必须通过发布平台打的包才可以。

android H5离线包实现 h5离线包是什么_android H5离线包实现

 

2.预制离线包的方法:将预制的bundle路径,plist路径在代码指定,从发布平台下载离线包和json文件,离线包放到上面的路径下,把json字段填到plist里。

 [NBServiceConfigurationGet().appConfig setPresetApplistPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoPresetApps.bundle/NAMApplist.plist"] ofType:nil]];

[NBServiceConfigurationGet().appConfig setPresetAppPackagePath:[[NSBundle mainBundle] pathForResource:@"DemoPresetApps.bundle" ofType:nil]];

android H5离线包实现 h5离线包是什么_json_02

官网说用.json也可以 但是一直没弄成功。所以这里用的是plist.

 

3.如何验证打开的页面是否来自离线包?

首先想到的是hook系统的open方法,可是很遗憾只能看到plist调用了open。amr离线包没有.为什么呢?猜想是直接拷贝或解压的压缩包没有走open.

不联网打开客户端。

如果不点击对应功能,文件夹下是没有该文件的。

 

点击功能后,将模拟器或真机的沙盒文件打开,预制的amr文件不在NAMAPP_AMR下。

android H5离线包实现 h5离线包是什么_android H5离线包实现_03

NANAPP”文件夹下生成两个无后缀的文件,这两个文件以app和installedApp结尾。这两个文件通过open能看到。

android H5离线包实现 h5离线包是什么_mpaas_04

NAMAPP_UNZIP这个文件夹里面有对应的解压后的文件(tar,CERT.json,Mainfest.json).tar也有open记录。

android H5离线包实现 h5离线包是什么_android H5离线包实现_05

 

4.蚂蚁的离线包容器如何打开另一个页面还能整体滑动返回?

猜测:打开一个页面的时候需要把需要的参数都带过来,alloc新的控制器,uiwebview重新把这个离线包再加载一遍.加载页面时根据不同路由进不同页面。

 

5.h5发请求是使用的原生通道,可是没有发现哪个jsapi是。

通过交换蚂蚁的发请求方法可以看到,h5发请求的代码被封装起来了。

#import "DTRpcClient+YYY.h"

#import <objc/runtime.h>

@implementation DTRpcClient (YYY)

+ (void)load{

    {

        Method originalMethod = class_getInstanceMethod([NSClassFromString(@"DTRpcClient") class], @selector(executeMethod:params:requestHeaderField:responseHeaderFields:));

        Method swizzledMethod = class_getInstanceMethod([self class], @selector(SexecuteMethod:params:requestHeaderField:responseHeaderFields:));

        method_exchangeImplementations(originalMethod, swizzledMethod);

    }

}

- (id)SexecuteMethod:(DTRpcMethod *)method params:(NSArray *)params requestHeaderField:(NSDictionary*)field responseHeaderFields:(void (^)(NSDictionary* allHeaderFields))responseBlock;{

   

    return  [self SexecuteMethod:method params:params requestHeaderField:field responseHeaderFields:responseBlock];

}

android H5离线包实现 h5离线包是什么_离线包_06

使用的是H5RPCCaller这个类的callRPC方法

 

6.离线包里面的h5代码是加密混淆过的

 

7.通过交换蚂蚁的PSDWebViewURLProtocol类的canInitWithRequest方法发现,打开一个h5功能时,仅对第一页的文件加载,跳入第二页才加载第二页的js和css,html.

//
//  PSDWebViewURLProtocol+YYY.h
//  HXMobileBank
//
//  Created by YYY on 2019/9/10.
//  Copyright © 2019 Alibaba. All rights reserved.
//



NS_ASSUME_NONNULL_BEGIN
@interface PSDWebViewURLProtocol:NSObject
@end

@interface PSDWebViewURLProtocol (YYY)

@end

NS_ASSUME_NONNULL_END
//
//  PSDWebViewURLProtocol+YYY.m
//  HXMobileBank
//
//  Created by YYY on 2019/9/10.
//  Copyright © 2019 Alibaba. All rights reserved.
//

#import "PSDWebViewURLProtocol+YYY.h"

@implementation PSDWebViewURLProtocol (YYY)
+ (void)load{
    {
        Method originalMethod = class_getClassMethod([NSClassFromString(@"PSDWebViewURLProtocol") class], @selector(canInitWithRequest:));
        
        Method swizzledMethod = class_getClassMethod([self class], @selector(canInitWithRequestS:));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

+ (BOOL)canInitWithRequestS:(NSMutableURLRequest *)request {
    
    NSLog(@"PSDWebViewURLProtocol canInitWithRequestS %@" ,request);;
    return [self canInitWithRequestS:request];
}
@end