WEEX + HTTPDNS iOS解决方案

简介: ## WEEX + HTTPDNS iOS解决方案 由于`WebView`并未暴露处设置DNS的接口,因而在`WebView`场景下使用`HttpDns`存在很多无法限制,但如果接入`WEEX`,则可以较好地植入`HTTPDNS`,本文主要介绍在`WEEX`场景下接入`HTTPDNS`的方案细节。 在`WEEX`运行时环境下,所有的逻辑最终都会转换到`Native Runtime`中执

WEEX + HTTPDNS iOS解决方案

由于WebView并未暴露处设置DNS的接口,因而在WebView场景下使用HttpDns存在很多无法限制,但如果接入WEEX,则可以较好地植入HTTPDNS,本文主要介绍在WEEX场景下接入HTTPDNS的方案细节。

WEEX运行时环境下,所有的逻辑最终都会转换到Native Runtime中执行,网络请求也不例外。同时WEEX也提供了自定义相应实现的接口,通过重写网络请求适配器,我们可以较为简单地接入HTTPDNS。在WEEX运行环境中,主要有两种网络请求:

  • 通过Stream进行的网络请求
  • <image>标签指定的加载图片的网络请求

下面以 weex iOS 0.7.0 版本为例:

Stream网络请求 + HTTPDNS

Stream网络请求在 iOS 端最终会通过WXNetworkDefaultImpl完成,同时WEEX也提供了相应的接口自定义网络请求适配器。具体的逻辑如下:

第一步:创建自定义网络请求适配器,实现 WXNetworkHttpDnsImpl 接口

#import <WeexSDK/WeexSDK.h>
#import "WXNetworkDefaultImpl.h"

@interface WXNetworkHttpDnsImpl : NSObject<WXNetworkProtocol, WXModuleProtocol , NSURLSessionDelegate>

@end

第二步:在WEEX初始化时注册自定义网络适配器,替换默认适配器:

    [WXSDKEngine registerHandler:[WXNetworkHttpDnsImpl new] withProtocol:@protocol(WXNetworkProtocol)];

之后的网络请求都会通过WXNetworkHttpDnsImpl实现,所以只需要在WXNetworkHttpDnsImpl中植入 HTTPDNS 逻辑即可,具体逻辑可以参考如下代码:

#import "WXNetworkDefaultImpl.h"

@interface WXNetworkCallbackInfo : NSObject

@property (nonatomic, copy) void(^sendDataCallback)(int64_t, int64_t);
@property (nonatomic, copy) void(^responseCallback)(NSURLResponse *);
@property (nonatomic, copy) void(^receiveDataCallback)(NSData *);
@property (nonatomic, strong) NSMutableData *data;
@property (nonatomic, copy) void(^compeletionCallback)(NSData *, NSError *);

@end

@implementation WXNetworkCallbackInfo

@end

@implementation WXNetworkDefaultImpl
{
    NSMutableDictionary *_callbacks;
    NSURLSession *_session;
}

- (id)sendRequest:(NSURLRequest *)request withSendingData:(void (^)(int64_t, int64_t))sendDataCallback
                                             withResponse:(void (^)(NSURLResponse *))responseCallback
                                          withReceiveData:(void (^)(NSData *))receiveDataCallback
                                          withCompeletion:(void (^)(NSData *, NSError *))compeletionCallback
{
    WXNetworkCallbackInfo *info = [WXNetworkCallbackInfo new];
    info.sendDataCallback = sendDataCallback;
    info.responseCallback = responseCallback;
    info.receiveDataCallback = receiveDataCallback;
    info.compeletionCallback = compeletionCallback;
    
    if (!_session) {
        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                 delegate:self
                                            delegateQueue:[NSOperationQueue mainQueue]];
    }
    
    NSURLSessionDataTask *task = [_session dataTaskWithRequest:request];
    if (!_callbacks) {
        _callbacks = [NSMutableDictionary dictionary];
    }
    [_callbacks setObject:info forKey:task];
    [task resume];
    
    return task;
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                                didSendBodyData:(int64_t)bytesSent
                                 totalBytesSent:(int64_t)totalBytesSent
                       totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
    WXNetworkCallbackInfo *info = [_callbacks objectForKey:task];
    if (info.sendDataCallback) {
        info.sendDataCallback(totalBytesSent, totalBytesExpectedToSend);
    }
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)task
                                 didReceiveResponse:(NSURLResponse *)response
                                  completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
    WXNetworkCallbackInfo *info = [_callbacks objectForKey:task];
    if (info.responseCallback) {
        info.responseCallback(response);
    }
    completionHandler(NSURLSessionResponseAllow);
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)task didReceiveData:(NSData *)data
{
    WXNetworkCallbackInfo *info = [_callbacks objectForKey:task];
    if (info.receiveDataCallback) {
        info.receiveDataCallback(data);
    }
    
    NSMutableData *mutableData = info.data;
    if (!mutableData) {
        mutableData = [NSMutableData new];
        info.data = mutableData;
    }
    
    [mutableData appendData:data];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    WXNetworkCallbackInfo *info = [_callbacks objectForKey:task];
    if (info.compeletionCallback) {
        info.compeletionCallback(info.data, error);
    }
    [_callbacks removeObjectForKey:task];
}

@end

1.2 <image>网络请求 + HTTPDNS

WEEX并没有提供默认的图片适配器实现,所以用户必须自行实现才能完成图片请求逻辑,具体步骤分为以下几步:

第一步:自定义图片请求适配器,实现IWXImgLoaderAdapter接口

#import "WXImgLoaderProtocol.h"

@interface WXImgLoaderDefaultImpl : NSObject<WXImgLoaderProtocol, WXModuleProtocol>
@end

第二步:在WEEX初始化时注册该图片适配器:

   [WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];

所以同WXNetworkHttpDnsImpl一样,我们只需在WXNetworkHttpDnsImpl植入HTTPDNS逻辑即可。

相关文章
|
JSON 缓存 Android开发
iOS高质量的动画实现解决方案——Lottie
iOS高质量的动画实现解决方案——Lottie
988 0
|
4月前
|
移动开发 安全 前端开发
uniapp打包iOS应用并通过审核:代码混淆的终极解决方案 ✨
本篇博客将教你如何使用 JavaScript-obfuscator 插件来一键发行和混淆 iOS 上的 uniapp 代码。通过安装插件、创建运行脚本,并执行混淆操作,你将能够轻松通过审核,提高应用程序的安全性。🔒
|
8月前
|
Web App开发 JavaScript iOS开发
iOS Safari 浏览器 100vh 带有滚动条解决方案
iOS Safari 浏览器 100vh 带有滚动条解决方案
452 0
|
9月前
|
JavaScript 前端开发 iOS开发
javascript格式化时间:ios不支持时间戳转换解决方案
javascript格式化时间:ios不支持时间戳转换解决方案
153 0
|
移动开发 JavaScript weex
weex-自定义module,实现weex在iOS的本地化,js之间互相跳转,交互,传值(iOS接入weex的最佳方式)
weex-自定义module,实现weex在iOS的本地化,js之间互相跳转,交互,传值(iOS接入weex的最佳方式)
219 0
|
移动开发 weex API
weex在iOS环境加载本地图片的方法
weex在iOS环境加载本地图片的方法
140 0
weex在iOS环境加载本地图片的方法
|
移动开发 weex iOS开发
weex run ios 不成功问题
weex run ios 不成功问题
83 0
|
算法 安全 Java
IOS 联真机签名解决方案
IOS 联真机签名解决方案
IOS 联真机签名解决方案
|
JavaScript 安全 Android开发
Vue.js - 单页面 SPA ,IOS 端页面跳转后调用微信 JSSDK 时报错: &quot;invalid signature&quot; 解决方案
Vue.js - 单页面 SPA ,IOS 端页面跳转后调用微信 JSSDK 时报错: &quot;invalid signature&quot; 解决方案
414 0
|
开发工具 iOS开发 Perl
关于flutter_module嵌入ios原生项目报错:dyld: Library not loaded: @rpath/App.framework/App解决方案
上个星期,突然有一位做flutter开发的小伙伴添加了我的微信,说他的项目中报dyld: Library not loaded: @rpath/App.framework/App这个错误,说是采用我之前的文章Flutter-module嵌入iOS原生老项目中中的方法可以解决,但是他们是团队开发,路径写死对多人开发不够友好,问我有没有其他解决方案。
关于flutter_module嵌入ios原生项目报错:dyld: Library not loaded: @rpath/App.framework/App解决方案