# 現實生活中常見的問題

## 他山之石

pub.dev

## 網路的互動

http: ^0.13.3

flutter\_html: ^2.1.2

http 302 redirect

```
Future<String> getRealImgUrl(String urlString) async {
  var client = baseClient();

  http.Request req = http.Request("Get", Uri.parse(urlString))
    ..followRedirects = false;

  try {
    http.StreamedResponse response = await client.send(req);
    if (response.statusCode == 302) {
      return await getRealImgUrl(response.headers['location']);
    } else if (response.statusCode == 200) {
      return urlString;
    }
  } finally {
    client.close();
  }

  return "";
}

```

## Debug

break point

## Uri parse / Url encode / decode

## Object Mapping

Local Storage

## Function / CallBack

Fun&#x20;

exception

`try/catch/finally`

`exception`

## 型別轉換

is Type

```
print(("" is String).toString());
```

## Extension methods

```
extension AkiStringExtension on String {
  DateTime stringToDate(
      {bool parseUTC = false}) {
    String fromPattern = "yyyy-MM-dd'T'HH:mm:ss";  
    final fromFormatter = DateFormat(fromPattern);
    if (parseUTC) {
      return fromFormatter.parseUTC(this);
    } else {
      return fromFormatter.parseUTC(this).toLocal();
    }
  }
```

## 常用的WIDGET / 按鈕 / 布局

Icons / Images

Collection

map / filter / where / first / toList()

```
myList.asMap().entries.map((entry) {
    int idx = entry.key;
    String val = entry.value;

    return something;
}).toList();
```

snackbar

字體

## 顏色

const Color blue = Color(0xFF008BCD);

```
Color fromHex(String hexString) {
  final buffer = StringBuffer();
  if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
  buffer.write(hexString.replaceFirst('#', ''));
  return Color(int.parse(buffer.toString(), radix: 16));
}
```

extension

```
extension AkiColorExtension on String {
  Color toColor() {
    final buffer = StringBuffer();
    if (this.length == 6 || this.length == 7) buffer.write('ff');
    buffer.write(this.replaceFirst('#', ''));
    return Color(int.parse(buffer.toString(), radix: 16));
  }
}
```

加解密

多語系

多環境開發

EasyLoading

```
EasyLoading.init(builder: (context, widget) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
          child: widget!,
        )
```

不同手機的螢幕尺寸處理

動畫

Push

Deep Link

## 與原生互動

### Method Channel

Flutter

```
Future<String> getDeviceIDFV() async {
  const platform = const MethodChannel('com.yuaki/utils');

  try {
    return await platform.invokeMethod('getDeviceIDFV');
  } on PlatformException catch (_) {
    return "";
  }
}
```

iOS

```
 let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let customChannel = FlutterMethodChannel(name: "com.yuaki/utils",
                                                 binaryMessenger: controller.binaryMessenger)
        customChannel.setMethodCallHandler({(call: FlutterMethodCall, result: FlutterResult) -> Void in
            
            switch call.method {
            case "getDeviceIDFV":
                result(getDeviceIDFV())
                break;
            case "setBadgeNum":
                guard let args = call.arguments as? [String: Int] else {
                    result(FlutterError.init(code: "1", message: "Parameters Error", details: nil))
                    return
                }
                
                guard let number: Int = args["number"] else {
                    result(FlutterError.init(code: "2", message: "Parameters Error", details: nil))
                    return
                }
                
                result(self.setBadgeNum(number))
                break;
                
            case "getDeviceToken":
                result("\(UserDefaults.standard.object(forKey:"DeviceToken") ?? "")")
                break;
            case "getFirebaseToken":
                result(UserDefaults.standard.object(forKey:"FireBaseToken") ?? "")
                break;
                
            default:
                result(FlutterMethodNotImplemented)
            }
        })
        
        
```

```
func getDeviceIDFV()->String {
    var idfv : String = UserDefaults.standard.object(forKey: "APP_DEVICE_IDFV") as? String ?? ""
    
    if(idfv == ""){
        idfv = UIDevice.current.identifierForVendor?.uuidString ?? ""
        if(idfv != ""){
            UserDefaults.standard.setValue(idfv, forKey: "APP_DEVICE_IDFV")
            UserDefaults.standard.synchronize();
        }
    }
    return idfv;
}

```

Android

```
 private val CHANNEL = "com.yuaki/utils"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.flutterEngine?.let {

            val methodChannel = MethodChannel(it.getDartExecutor(), CHANNEL)

            methodChannel.setMethodCallHandler(object : MethodCallHandler {
                override fun onMethodCall(methodCall: MethodCall, result: MethodChannel.Result) {
                    if ("getDeviceIDFV" == methodCall.method) {
                        result.success(getDeviceIDFV(context))
                    } else {
                        result.notImplemented()
                    }
                }

            })
        };
    }
```

```
fun getDeviceIDFV(c:Context): String? {
    return Secure.getString(c.getContentResolver(),
            Secure.ANDROID_ID)
}
```

Flutter SDK/Library of Native APP

Theme / Light Mode / Dark Mode
