WEEX + HTTPDNS iOS解决方案

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: ## 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逻辑即可。

相关文章
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
77 7
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
3月前
|
测试技术 开发工具 iOS开发
iOS自动化测试方案(三):WDA+iOS自动化测试解决方案
这篇文章是iOS自动化测试方案的第三部分,介绍了在没有MacOS系统条件下,如何使用WDA(WebDriverAgent)结合Python客户端库facebook-wda和tidevice工具,在Windows系统上实现iOS应用的自动化测试,包括环境准备、问题解决和扩展应用的详细步骤。
256 1
iOS自动化测试方案(三):WDA+iOS自动化测试解决方案
|
6月前
|
存储 Android开发 iOS开发
iOS不支持HEIC格式的图片显示和标签函数显示问题及解决方案
iOS不支持HEIC格式的图片显示和标签函数显示问题及解决方案
206 0
|
3月前
|
前端开发 开发工具 Android开发
探索安卓与iOS应用开发:跨平台解决方案的崛起
【8月更文挑战第27天】在移动设备日益普及的今天,安卓和iOS系统占据了市场的主导地位。开发者们面临着一个重要问题:是选择专注于单一平台,还是寻找一种能够同时覆盖两大系统的解决方案?本文将探讨跨平台开发工具的优势,分析它们如何改变了移动应用的开发格局,并分享一些实用的开发技巧。无论你是新手还是资深开发者,这篇文章都将为你提供有价值的见解和建议。
|
3月前
|
前端开发 JavaScript Android开发
探索Android和iOS开发中的跨平台解决方案
【8月更文挑战第1天】随着移动应用市场的不断扩张,开发者面临一个共同的挑战——如何高效地为多个平台创建和维护应用程序。本文将深入探讨跨平台开发工具,特别是Flutter和React Native,通过比较它们的优势和限制,并辅以实际代码示例,揭示这些工具如何帮助开发者在保持高性能的同时,实现代码的最大化重用。
|
3月前
|
前端开发 JavaScript Android开发
安卓与iOS开发中的跨平台解决方案
【8月更文挑战第24天】在移动应用开发领域,安卓和iOS两大平台占据了主导地位。然而,为这两个平台分别开发和维护应用会带来额外的时间和成本。本文将探讨跨平台开发的概念、优势以及流行的跨平台框架,如React Native和Flutter,并分析它们如何解决多平台开发的挑战。
|
6月前
|
存储 Web App开发 Android开发
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
647 1
iOS不支持WebP格式图片解决方案和iPhone 7及其后硬件拍照的HEIC格式图片
|
6月前
|
程序员 定位技术 开发工具
iOS11及以上操作系统无法定位问题完美解决方案
iOS11及以上操作系统无法定位问题完美解决方案
69 1
|
6月前
|
iOS开发
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
789 0