1。我必须获取 iOS 设备的位置,但我没有使用 flutter 包。我需要从 swift 代码中获取它并将其传递给 flutter。
我没有任何 swift 经验。我已经使用了以下代码。有人可以帮忙吗?
import UIKit
import Flutter
import CoreLocation
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let testChannel = FlutterMethodChannel(name: "com.example.testFlutter/test",
binaryMessenger: controller.binaryMessenger)
testChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
// This method is invoked on the UI thread.
if call.method == "getLocation"{
self?.getLocation(result: result)
}
else{
result(FlutterMethodNotImplemented)
return
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func getLocation(result: FlutterResult){
var locationManager: CLLocationManager?
locationManager?.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager?.startUpdatingLocation()
result("updating location")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation], result: FlutterResult) {
result("testing")
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
result("location = \(locValue.latitude) \(locValue.longitude)")
}
}
2。 Flutter这边的代码是
static const platform = MethodChannel('com.example.testFlutter/test');
printMsgFromiOS() async {
try {
final String result = await platform.invokeMethod('getLocation');
print(result);
} on PlatformException catch (e) {
print(e.message);
}
}
@override
void initState() {
// TODO: implement initState
super.initState();
printMsgFromiOS();
}
输出 运行代码时,它没有错误,并且我将 String 作为输出。 String是“updating location”,这是Swift代码的getLocation()函数中的语句。
A 部分 - 一次性地点
我正在为我的问题提供一个答案,它让我使用以下代码从 Swift 到 Flutter 的一次定位。但是,我正在尝试找到一种解决方案,以便在每次更改时获取位置更新,如果成功,我会发布它。
(更新 - 多次获取位置的解决方案在下面的 B 部分中可用)。
1。与有问题的代码相比,更新了 Swift 代码
import UIKit
import Flutter
import CoreLocation
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let testChannel = FlutterMethodChannel(name: "com.example.testFlutter/test",
binaryMessenger: controller.binaryMessenger)
testChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
// This method is invoked on the UI thread.
if call.method == "getLocation"{
self?.getLocation(result: result)
}
else{
result(FlutterMethodNotImplemented)
return
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func getLocation(result: FlutterResult){
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
if let location = locationManager.location?.coordinate {
let string = "\(location.latitude), \(location.longitude)"
result(string)
} else {
// Handle error
result("Error")
}
}
}
2。 Flutter 代码与问题中的相同
3。输出
B 部分 - 多次地点
EventChannel 在下面的代码中用于从 swift 中多次获取位置。我曾尝试使用删除,但是没有用,我仍在努力。现在,我决定使用计时器。
1。斯威夫特代码
import UIKit
import Flutter
import CoreLocation
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, CLLocationManagerDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let testChannel = FlutterEventChannel(name: "com.example.testFlutter/test",
binaryMessenger: controller.binaryMessenger)
let swiftTestChannel = SwiftTestChannel()
swiftTestChannel.setup(flutterViewController: controller)
testChannel.setStreamHandler(swiftTestChannel)
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func getLocation(result: FlutterResult){
// var locationManager: CLLocationManager?
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation], result: FlutterResult) {
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
result("")
}
}
class SwiftTestChannel: NSObject, FlutterStreamHandler, CLLocationManagerDelegate {
var eventSink: FlutterEventSink?
private let channelName = "mychannel"
func setup(flutterViewController: FlutterViewController) {
let channel = FlutterEventChannel(name: channelName, binaryMessenger: flutterViewController as! FlutterBinaryMessenger)
channel.setStreamHandler(self)
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
eventSink = events
let timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { _ in
// self.eventSink?("My string from Swift")
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
if let location = locationManager.location?.coordinate {
let string = "\(location.latitude), \(location.longitude)"
self.eventSink?(string)
} else {
// Handle error
self.eventSink?("Error")
}
}
// getLocation()
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
return nil
}
}
2。颤振代码
static const platform = EventChannel('com.example.testFlutter/test');
printMsgFromiOS() async {
try {
platform.receiveBroadcastStream().listen((data) {
print(data.toString());
});
} on PlatformException catch (e) {
print(e.message);
}
}
@override
void initState() {
// TODO: implement initState
super.initState();
printMsgFromiOS();
}
3。输出
您缺少将委托设置为自我。通过将委托设置为自我,您告诉位置管理器将位置更新发送到实现 CLLocationManagerDelegate 协议的对象。
private func getLocation(result: FlutterResult) {
let locationManager = CLLocationManager()
locationManager.delegate = self // set the delegate to self
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
result("updating location")
}
}
您需要将
CLLocationManager
的委托属性设置为您的AppDelegate
。
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, CLLocationManagerDelegate {