无法使用自定义平台特定代码从 swift 到 flutter 获取位置

问题描述 投票:0回答:2

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()函数中的语句。

ios swift flutter core-location
2个回答
1
投票

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。输出


0
投票

您缺少将委托设置为自我。通过将委托设置为自我,您告诉位置管理器将位置更新发送到实现 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 {
© www.soinside.com 2019 - 2024. All rights reserved.