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逻辑即可。

相关文章
|
Serverless 开发者 Docker
ModelScope问题之购买云服务器阿里云显示一直在准备中如何解决
ModelScope镜像是指用于在ModelScope平台上创建和管理的容器镜像,这些镜像包含用于模型训练和推理的环境和依赖;本合集将说明如何使用ModelScope镜像以及管理镜像的技巧和注意事项。
300 2
|
5月前
|
网络协议 安全 网络安全
雷池WAF+emby+ddnsgo搭建个人影音库,实现远程安全访问流媒体
雷池WAF+emby+ddnsgo搭建个人影音库,实现远程安全访问流媒体
358 4
|
网络性能优化
[VPP] vpp_com使用
[VPP] vpp_com使用
|
监控 安全 网络安全
边界防护
【8月更文挑战第18天】
502 2
|
数据可视化 Python
Python中的数据可视化:在数据点上添加标签
Python中的数据可视化:在数据点上添加标签
423 3
|
存储 BI Apache
下一代实时数据库:Apache Doris 【七】数据模型
下一代实时数据库:Apache Doris 【七】数据模型
318 1
|
机器学习/深度学习 自然语言处理 算法
【ACL 2023】面向轻量化文图检索的Dual-Encoder模型蒸馏算法ConaCLIP
ConaCLIP针对轻量化的图文检索任务进行设计,是一种通过全连接的知识交互图学习方式将知识从dual-encoder大模型中蒸馏到dual-encoder小模型的算法。
|
JavaScript 前端开发 API
在vue中如何获取项目src外层的config目录以及api接口proxy的target代理地址
在vue中如何获取项目src外层的config目录以及api接口proxy的target代理地址
187 0
|
运维 Prometheus Kubernetes
直播预告丨如何使用 KubeSkoop exporter 监测和定位容器网络抖动问题
直播预告丨如何使用 KubeSkoop exporter 监测和定位容器网络抖动问题
|
机器学习/深度学习 自然语言处理 搜索推荐
工业界常用的推荐系统模型有哪些?
最近收到很多同学的提问,目前工业界常用的推荐系统模型有哪些?CTR和推荐算法有什么本质区别?推荐系统中如何做 User Embedding?橙子邀请了淘系技术部的豆苗同学对以上问题进行解答,也欢迎大家一起交流。
工业界常用的推荐系统模型有哪些?