在我们的项目开发过程中,网络请求是必不可少的。网络请求包含使用客户端代码实现,也可以在js页面直接发起请求。本章重点讲述如何搭建网络架构。
-
Android端
架构描述:采用retrofit2实现网络请求。这段代码比较简单,举个简单列子:使用新浪的短链服务生成短链接。我们看下怎么实现。
网络请求实现,先看retrofit2请求api实现,如下代码:public interface RNNetConnectApi { //接口请求格式 @Headers({ "Content-Type:application/x-www-form-urlencoded", "Accept-Charset: utf-8" }) //接口名称,这是一个get请求。 //url_long:我们需要转化的长链接 @GET("shorten.json") Call<String> getShortLinkUrl(@Query("source") String appKey, @Query("url_long") String url_long); }
然后我们还要初始化我们的retrofit api句柄.如下代码实现:
/** *retrofit创建 * @return */ protected void createRetrofit() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout((long)this.connectTime, TimeUnit.SECONDS); builder.readTimeout((long)this.connectTime, TimeUnit.SECONDS); builder.writeTimeout((long)this.connectTime, TimeUnit.SECONDS); builder.retryOnConnectionFailure(false); builder.addInterceptor(new NetInterceptor()); OkHttpClient okHttpClient = builder.build(); Retrofit retrofit = (new retrofit2.Retrofit.Builder()).baseUrl(urlHost).client(okHttpClient) .addConverterFactory(ScalarsConverterFactory.create()).build(); rnNetConnectApi = retrofit.create(RNNetConnectApi.class); }
定义成功后,我们就可以用这个api接口来创建Call对象,实现网络请求:
Call call = rnNetConnectApi.getShortLinkUrl(appKey,longUrl); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { handleResponse(call,response,callback); } @Override public void onFailure(Call call, Throwable t) { if ( null != t) { Log.d(TAG,"请求失败信息:"+t.getMessage()+" 原因:"+t.getCause()); } } });
网络请求成功后,我们在handleResponse这个方法中具体处理。主要的网络处理代码就是这么多。
-
IOS端
网络请求架构:我们采用的是AFNetworking架构。代码主要描述如下:
//执行网络请求- (void)getShorLinktUrl: (NSString*)longUrl success:(RCTResponseSenderBlock)callback { NSString *urlHost = @"http://api.t.sina.com.cn/short_url/shorten.json?source=3271760578&&url_long="; urlHost = [urlHost stringByAppendingString:longUrl]; NSURL *url = [NSURL URLWithString: urlHost]; NSURLSession *session = [NSURLSession sharedSession]; //创建可变的请求对象 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //配置网络请求格式 NSString *contentType = [NSString stringWithFormat:@"text/plain"]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; NSString *accept = [NSString stringWithFormat:@"application/json"]; [request setValue:accept forHTTPHeaderField: @"Accept"]; //建立请求task NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable responseData, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; if ( nil != httpResponse) { NSLog(@"response status = %d",(int)httpResponse.statusCode); if ( nil != error) { NSLog(@"response error = %@",error); } } //正确的应答 if ( nil != httpResponse && httpResponse.statusCode == 200) { //解析数据:根据需要处理 //NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil]; NSLog(@"response result = %@",result); if ([result isKindOfClass:[NSArray class]]) { NSDictionary *item = (NSDictionary*)[(NSArray*)result objectAtIndex:0]; for (NSString *key in item) { //存入数组并同步 [[NSUserDefaults standardUserDefaults] setObject:item[key] forKey:key]; [[NSUserDefaults standardUserDefaults] synchronize]; NSLog(@"key: %@ value: %@", key, item[key]); } } else { for (NSString *key in result) { //存入数组并同步 [[NSUserDefaults standardUserDefaults] setObject:result[key] forKey:key]; [[NSUserDefaults standardUserDefaults] synchronize]; NSLog(@"key: %@ value: %@", key, result[key]); } } } }]; //读取数据 NSString *shortUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"url_short"]; if ( nil != shortUrl) { NSLog(@"shortUrl = %@",shortUrl); callback(@[shortUrl,]); } else { callback(@[@"获取失败",]); } [dataTask resume]; } 核心代码基本上就这么多。
-
js端
我们先来看一下使用客户端网络请求,如何操作:nativeModule.doNetworkRequest(longUrl,this.callBack);
其中longUrl是我们具体要转成短链的长链接地址,callBack是回调方法,必须加上this调用指定作用域。
如果需要网页动态刷新显示结果,我们可以用如下方式实现:this.setState({ shortUrl: url, })
使用setState就会再次调用render方法去刷新,但是使用this.state就不会。注意:必须在构造函数中初始化。类似如下操作;
constructor(props){ super(props); this.state = { shortUrl: "本地获取数据中。。。", //这里放你自己定义的state变量及初始值 jsUrl: "页面获取数据中。。。", //这里放你自己定义的state变量及初始值 }; this.getDataFromNet(); this.fetchData(); }
否则在render中如果使用state中的变量,就会报null错误。
看一下第二方式,就是页面直接发起请求,我们使用fetch来实现:
//由页面发起请求 fetchData() { fetch(urlHost+longUrl) .then((response) => response.json()) .then((responseData) => { //过来的数据是一个JSONArray格式,要使用这种方式取值 console.log("responseData[0]=",responseData[0]); //设置3秒后刷新页面 setTimeout(()=> { this.setState({ jsUrl: responseData[0].url_short, }); }, delay_time); }) .done(); //调用了done() —— 这样可以抛出异常而不是简单忽略 }
至此,网络请求基本上就实现了。