Chapter 3 The first project of RN: Realization of network requests

Posted by sohdubom on Thu, 16 May 2019 00:56:46 +0200

Network requests are essential to our project development.A network request consists of a client-side code implementation or can be initiated directly from a js page.This chapter focuses on how to build a network architecture.

  1. Android side
    Architecture description: Use retrofit2 to implement network requests.This code is relatively simple, let's say a simple column: use Sina's short-chain service to generate short links.Let's see how that works.
    Network request implementation, first look at retrofit2 request api implementation, as follows:

    public interface RNNetConnectApi {
        //Interface Request Format
        @Headers({
                "Content-Type:application/x-www-form-urlencoded",
                "Accept-Charset: utf-8"
        })
    
        //Interface name, this is a get request.
        //url_long: The long link we need to transform
        @GET("shorten.json")
        Call<String> getShortLinkUrl(@Query("source") String appKey, @Query("url_long") String url_long);
    }
    

    Then we'll initialize our retrofit api handle. The following code implements it:

       /**
       *retrofit Establish
       * @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);
        }
    

    Once defined successfully, we can use this api interface to create a Call object to fulfill network requests:

    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,"Request Failure Information:"+t.getMessage()+" Reason:"+t.getCause());
            }
        }
    });
    

    After the network request succeeds, we handle it specifically in the handleResponse method.That's the main network processing code.

  2. IOS End
    Network Request Architecture: We used the AFNetworking architecture.The code is mainly described as follows:
    //Perform network requests

    - (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];
        
        //Create variable request objects
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        //Configure Network Request Format
        NSString *contentType = [NSString stringWithFormat:@"text/plain"];
        [request setValue:contentType forHTTPHeaderField: @"Content-Type"];
        NSString *accept = [NSString stringWithFormat:@"application/json"];
        [request setValue:accept forHTTPHeaderField: @"Accept"];
        
        //Create Request 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);
                }
            }
            
            //Correct answer
            if ( nil != httpResponse && httpResponse.statusCode == 200) {
                //Parsing data: Processing as needed
                //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) {
                        //Save in Array and Synchronize
                        
                        [[NSUserDefaults standardUserDefaults] setObject:item[key] forKey:key];
                        
                        [[NSUserDefaults standardUserDefaults] synchronize];
                        
                        NSLog(@"key: %@ value: %@", key, item[key]);
                    }
                } else {
                    for (NSString *key in result) {
                        //Save in Array and Synchronize
                        
                        [[NSUserDefaults standardUserDefaults] setObject:result[key] forKey:key];
                        
                        [[NSUserDefaults standardUserDefaults] synchronize];
                        
                        NSLog(@"key: %@ value: %@", key, result[key]);
                    }
                }
            }
        }];
        
        //Read data
        NSString *shortUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"url_short"];
      
        if ( nil != shortUrl) {
          NSLog(@"shortUrl = %@",shortUrl);
          callback(@[shortUrl,]);
          
        } else {
          callback(@[@"Get Failed",]);
        }
      
        [dataTask resume];
    }
    //That's basically the core code.
    
  3. js-side
    Let's first look at how client network requests work:

    nativeModule.doNetworkRequest(longUrl,this.callBack);
    

    Where longUrl is a long link address that we specifically want to convert to a short chain, callBack is a callback method, and the scope must be specified with this call.
    If you need a dynamic refresh of the display results from a web page, we can do this as follows:

        this.setState({
            shortUrl: url,
    
        })
    

    Using setState, the render method is called again to refresh, but not with this.state.Note: Must be initialized in the constructor.Similar to the following operations;

    constructor(props){
        super(props);
        this.state = {
                   shortUrl: "Get data locally...",  //Put your own state variable and initial value here
                   jsUrl: "Page to get data.",  //Put your own state variable and initial value here
                };
        this.getDataFromNet();
        this.fetchData();
    }   
    

    Otherwise, if you use variables in the state in render, a null error will be reported.

    Take a look at the second way, that is, the page makes the request directly, and we use fetch to do this:

    //Initiate Request from Page
    fetchData() {
            fetch(urlHost+longUrl)
                .then((response) => response.json())
                .then((responseData) => {
                    //The data is in a JSONArray format, so use this to get the value
                    console.log("responseData[0]=",responseData[0]);
                    //Refresh page after 3 seconds
                    setTimeout(()=> {
                        this.setState({
                            jsUrl: responseData[0].url_short,
    
                        });
                    }, delay_time);
                })
                .done();
            //done() called - this allows exceptions to be thrown rather than simply ignored
        }         
    

    So far, network requests have basically been fulfilled.

Topics: network Retrofit JSON Session