Flutter代碼錦囊---根據環境選擇URL地址

現在要給公司開發一個內部使用的APP,但是因爲是小公司,沒有多餘的服務器資源,只能拿公司的主機當服務器,也只能在通過映射實現外網訪問。所以呀,很蛋疼,只能想辦法判斷用戶是在內網使用APP,還是在外網使用APP,然後根據環境選擇URL請求的IP地址。

首先是新建一個dart文件,把Flutter應用和頁面的架子搭起來,然後運行調試,確認應用可以正常跑起來。

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold( 
    );
  }
}

雖然很容易發出網絡請求,但使用原始的Future <http.Response>並不是很方便。所以,爲了讓我們的開發更輕鬆一些,我們可以將http.Response轉換爲我們自己的Dart對象。

首先,我們需要創建一個ComeBack類,其中包含來自網絡請求的數據。它還將包含一個工廠構造函數,允許我們從json創建一個ComeBack。當然,手動轉換JSON只是一種選擇,還可以用JSON和序列化。

class ComeBack {
  final int code;
  final String msg;
  final  data;

  ComeBack({
    this.code,
    this.msg,
    this.data,
  });

  factory ComeBack.fromJson(Map<String, dynamic> json) {
    return ComeBack(
      code: json['code'],
      msg: json['msg'],
      data: json['data'],
    );
  }
}

給兩個固定的內網/外網地址,再定義一個全局變量來承載實際的請求地址。

final String urlExtranet = 'http://218.15.158.64:8001/';
final String urlIntranet = 'http://192.168.9.247/';

String url = '';

http.get方法返回包含Response的Future,Future是用於處理異步操作的核心Dart類,它用於表示將來某個時間可用的潛在值或錯誤信息。http.Response類包含從成功的http調用接收的數據。

如果對內網IP(urlIntranet)的調用成功,則說明當前用戶處於內網環境,那麼接下來使用的都是內網IP。如果該調用不成功,則拋出錯誤,那麼就立即切換爲外網IP繼續訪問。

Future<ComeBack> fetchToken() async {
  url = urlIntranet;
  await http.get(url).catchError(
    (error) {
      url = urlExtranet;
    }
  );

  final response = await http.post(
    url + 'api/apirunner/auth/',
    body: {'username': 'username', 'password': 'password'},
  );

  if (response.statusCode == 200) {
    return ComeBack.fromJson(json.decode(response.body));
  } else {
    throw Exception('無法加載數據');
  }
}

爲了獲取數據並將其顯示在屏幕上,我們可以使用FutureBuilder組件, FutureBuilder組件附帶Flutter,可以輕鬆使用異步數據源。

future參數表示我們希望使的Future,在我們的例子中,我們將調用我們的fetchToken()函數。

builder參數是一個構建器函數,它告訴Flutter要呈現什麼,具體取決於Future的狀態:加載中、請求成功或請求錯誤。

  ………
    return new Scaffold( 
      body: FutureBuilder<ComeBack>(
        future: fetchToken(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Text(snapshot.data.data);
          } else if (snapshot.hasError) {
            return Center(
              child: SizedBox(
                height: 92.0,
                child: Column(
                  children: <Widget>[
                    Icon(
                      Icons.sentiment_very_dissatisfied,
                      size: 32.0,
                    ),
                    Text('${snapshot.error}'),
                  ],
                ),
              ),
            );
          }
          return Center(
            child: CircularProgressIndicator(),
          );
        },
      ),
    );
  ………

如下,屏幕可以會出現三種狀態:加載中狀態、請求成功狀態和請求錯誤狀態,請求錯誤狀態會顯示錯誤信息。

根據環境選擇URL地址效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章