# 插件開發:iOS端API實現
本節我們接著之前"獲取電池電量"插件的示例,來完成iOS端API的實現。以下步驟使用Objective-C,如果您更喜歡Swift,可以直接跳到后面Swift部分。
首先打開Xcode中Flutter應用程序的iOS部分:
1. 啟動 Xcode
2. 選擇 File > Open…
3. 定位到您 Flutter app目錄, 然后選擇里面的 `iOS`文件夾,點擊 OK
4. 確保Xcode項目的構建沒有錯誤。
5. 選擇 Runner > Runner ,打開`AppDelegate.m`
接下來,在`application didFinishLaunchingWithOptions:`方法內部創建一個`FlutterMethodChannel`,并添加一個處理方法。 確保與在Flutter客戶端使用的通道名稱相同。
```
#import <Flutter/Flutter.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
methodChannelWithName:@"samples.flutter.io/battery"
binaryMessenger:controller];
[batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
// TODO
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
```
接下來,我們添加Objective-C代碼,使用iOS電池API來獲取電池電量,這和原生是相同的。
在`AppDelegate`類中添加以下新的方法:
```
- (int)getBatteryLevel {
UIDevice* device = UIDevice.currentDevice;
device.batteryMonitoringEnabled = YES;
if (device.batteryState == UIDeviceBatteryStateUnknown) {
return -1;
} else {
return (int)(device.batteryLevel * 100);
}
}
```
最后,我們完成之前添加的`setMethodCallHandler`方法。我們需要處理的平臺方法名為`getBatteryLevel`,所以我們在call參數中需要先判斷是否為`getBatteryLevel`。 這個平臺方法的實現只需調用我們在前一步中編寫的iOS代碼,并使用result參數返回成功或錯誤的響應。如果調用了未定義的API,我們也會通知返回:
```
[batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
if ([@"getBatteryLevel" isEqualToString:call.method]) {
int batteryLevel = [self getBatteryLevel];
if (batteryLevel == -1) {
result([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"電池信息不可用"
details:nil]);
} else {
result(@(batteryLevel));
}
} else {
result(FlutterMethodNotImplemented);
}
}];
```
現在可以在iOS上運行該應用程序了,如果使用的是iOS模擬器,請注意,它不支持電池API,因此應用程序將顯示“電池信息不可用”。
### 使用Swift實現iOS API
以下步驟與上面使用Objective-C相似,首先打開Xcode中Flutter應用程序的iOS部分:
1. 啟動 Xcode
2. 選擇 File > Open…
3. 定位到您 Flutter app目錄, 然后選擇里面的 `ios`文件夾,點擊 OK
4. 確保Xcode項目的構建沒有錯誤。
5. 選擇 Runner > Runner ,然后打開`AppDelegate.swift`
接下來,覆蓋application方法并創建一個`FlutterMethodChannel`綁定通道名稱`samples.flutter.io/battery`:
```
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
GeneratedPluginRegistrant.register(with: self);
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController;
let batteryChannel = FlutterMethodChannel.init(name: "samples.flutter.io/battery",
binaryMessenger: controller);
batteryChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: FlutterResult) -> Void in
// Handle battery messages.
});
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
```
接下來,我們添加Swift代碼,使用iOS電池API來獲取電池電量,這和原生開發是相同的。
將以下新方法添加到`AppDelegate.swift`底部:
```
private func receiveBatteryLevel(result: FlutterResult) {
let device = UIDevice.current;
device.isBatteryMonitoringEnabled = true;
if (device.batteryState == UIDeviceBatteryState.unknown) {
result(FlutterError.init(code: "UNAVAILABLE",
message: "電池信息不可用",
details: nil));
} else {
result(Int(device.batteryLevel * 100));
}
}
```
最后,我們完成之前添加的`setMethodCallHandler`方法。我們需要處理的平臺方法名為`getBatteryLevel`,所以我們在call參數中需要先判斷是否為`getBatteryLevel`。 這個平臺方法的實現只需調用我們在前一步中編寫的iOS代碼,并使用result參數返回成功或錯誤的響應。如果調用了未定義的API,我們也會通知返回:
```
batteryChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: FlutterResult) -> Void in
if ("getBatteryLevel" == call.method) {
receiveBatteryLevel(result: result);
} else {
result(FlutterMethodNotImplemented);
}
});
```
現在可以在iOS上運行應用程序,如果使用的是iOS模擬器,請注意,它不支持電池API,因此應用程序將顯示“電池信息不可用”。
- 緣起
- 起步
- 移動開發技術簡介
- Flutter簡介
- 搭建Flutter開發環境
- 常見配置問題
- Dart語言簡介
- 第一個Flutter應用
- 計數器示例
- 路由管理
- 包管理
- 資源管理
- 調試Flutter APP
- Dart線程模型及異常捕獲
- 基礎Widgets
- Widget簡介
- 文本、字體樣式
- 按鈕
- 圖片和Icon
- 單選框和復選框
- 輸入框和表單
- 布局類Widgets
- 布局類Widgets簡介
- 線性布局Row、Column
- 彈性布局Flex
- 流式布局Wrap、Flow
- 層疊布局Stack、Positioned
- 容器類Widgets
- Padding
- 布局限制類容器ConstrainedBox、SizeBox
- 裝飾容器DecoratedBox
- 變換Transform
- Container容器
- Scaffold、TabBar、底部導航
- 可滾動Widgets
- 可滾動Widgets簡介
- SingleChildScrollView
- ListView
- GridView
- CustomScrollView
- 滾動監聽及控制ScrollController
- 功能型Widgets
- 導航返回攔截-WillPopScope
- 數據共享-InheritedWidget
- 主題-Theme
- 事件處理與通知
- 原始指針事件處理
- 手勢識別
- 全局事件總線
- 通知Notification
- 動畫
- Flutter動畫簡介
- 動畫結構
- 自定義路由過渡動畫
- Hero動畫
- 交錯動畫
- 自定義Widget
- 自定義Widget方法簡介
- 通過組合現有Widget實現
- 實例:TurnBox
- CustomPaint與Canvas
- 實例:圓形漸變進度條(自繪)
- 文件操作與網絡請求
- 文件操作
- Http請求-HttpClient
- Http請求-Dio package
- 實例:Http分塊下載
- WebSocket
- 使用Socket API
- Json轉Model
- 包與插件
- 開發package
- 插件開發:平臺通道簡介
- 插件開發:實現Android端API
- 插件開發:實現IOS端API
- 系統能力調用
- 國際化
- 讓App支持多語言
- 實現Localizations
- 使用Intl包
- Flutter核心原理
- Flutter UI系統
- Element和BuildContext
- RenderObject與RenderBox
- Flutter從啟動到顯示