使用 google_maps_flutter 在 IOS 上 Flutter App 崩溃

Flutter App crash on IOS by using google_maps_flutter

我正在创建我的第一个 Flutter 应用程序。该应用程序应在地图上的某些地方显示其他内容。对于地图,我使用 google_maps_flutter (https://pub.dev/packages/google_maps_flutter).

Android 一切正常。一旦我在 IOS 上启动应用程序并单击我的应用程序中的“地图”,应用程序就会在没有堆栈跟踪的情况下崩溃。 Android Studio 只是说“丢失与设备的连接”。

我在 Google 云平台上激活了 Android 和 IOS 的 SDK,并在我的项目中的 appDelegate.swift 添加了密钥。

我不明白。有谁知道是什么问题?非常感谢您的帮助 <3


这是我的 Class,其中 returns 带有 Google 地图小部件的脚手架:

class WaterMapScreen extends StatefulWidget {
  @override
  State<WaterMapScreen> createState() => _WaterMapScreenState();
}

class _WaterMapScreenState extends State<WaterMapScreen> {
  GetIt getIt = GetIt.instance;
  WaterService waterService;
  List<Section> sectionList;
  Location _location = new Location();
  StreamController<FavSection> _streamController =
      StreamController<FavSection>();
  Set<Polygon> polygonSet = new Set();
  UserService userService;
  FavSection _selectedSection;

  _WaterMapScreenState() {
    waterService = getIt.get<WaterService>();
    userService = getIt.get<UserService>();
  }

  initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        leading: IconButton(
            icon: Icon(Icons.arrow_back_outlined, color: Colors.orange),
            onPressed: () {
              Navigator.pop(context);
            }),
        title: Text(
          "Entdecken",
          style: TextStyle(fontWeight: FontWeight.bold, color: Colors.orange),
        ),
      ),
      body: Stack(children: <Widget>[
        getGoogleMapWithPolygons(),
        CustomSlidingPanel(stream: _streamController.stream),
      ]),
    );
  }

  FutureBuilder getGoogleMapWithPolygons() {
    return FutureBuilder(
        future: fetchSectionListWithFavorites(),
        builder: (BuildContext context, AsyncSnapshot sectionListAsync) {
          switch (sectionListAsync.connectionState) {
            case ConnectionState.none:
            case ConnectionState.waiting:
              return Center(
                  child: CircularProgressIndicator(color: Colors.orange));
            default:
              if (sectionListAsync.hasError) {
                print('Error: ${sectionListAsync.error}');
                return new Center(child: Text('Es ist ein Fehler aufgetreten'));
              } else {
                return FutureBuilder(
                    future: _location.getLocation(),
                    builder:
                        (BuildContext context, AsyncSnapshot locationAsync) {
                      switch (locationAsync.connectionState) {
                        case ConnectionState.none:
                        case ConnectionState.waiting:
                          return Center(
                              child: CircularProgressIndicator(
                                  color: Colors.orange));
                        default:
                          return GoogleMap(
                            initialCameraPosition: CameraPosition(
                                target: LatLng(locationAsync.data.latitude,
                                    locationAsync.data.longitude),
                                zoom: 10),
                            myLocationButtonEnabled: true,
                            mapType: MapType.normal,
                            myLocationEnabled: true,
                            polygons: sectionListAsync.data
                                .where((item) =>
                                    item.section.gewaesserTyp == "SEE" ||
                                    item.section.gewaesserTyp == "WEIER")
                                .map<Polygon>(
                                  (item) => Polygon(
                                    polygonId: PolygonId(item.section.id),
                                    points: item.section.paths
                                        .map<LatLng>((path) =>
                                            LatLng(path.lat, path.lng))
                                        .toList(),
                                    fillColor: Colors.orange.withOpacity(0.5),
                                    strokeColor: Colors.deepOrange,
                                    strokeWidth: 5,
                                    consumeTapEvents: true,
                                    onTap: () {
                                      _streamController
                                          .add(_selectedSection = item);
                                    },
                                  ),
                                )
                                .toSet(),
                            polylines: sectionListAsync.data
                                .where((item) =>
                                    item.section.gewaesserTyp == "BACH" ||
                                    item.section.gewaesserTyp == "FLUSS")
                                .map<Polyline>(
                                  (item) => Polyline(
                                    polylineId: PolylineId(item.section.id),
                                    points: item.section.paths
                                        .map<LatLng>((path) =>
                                            LatLng(path.lat, path.lng))
                                        .toList(),
                                    color: Colors.deepOrange,
                                    width: 5,
                                    consumeTapEvents: true,
                                    onTap: () {
                                      _streamController
                                          .add(_selectedSection = item);
                                    },
                                  ),
                                )
                                .toSet(),
                            onTap: (LatLng latLng) {
                              _streamController.add(_selectedSection = null);
                            },
                          );
                      }
                    });
              }
          }
        });
  }

这是我的 appDelegate.swift:

import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("MyTopSecretApiKey")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

我的pubspec.yaml:

name: fishr
description: Mobile Fishing Guide
version: 1.0.0+5

environment:
  sdk: ">=2.2.2 <3.0.0"
dependencies:
  shared_preferences: ^2.0.6
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  font_awesome_flutter: ^9.0.0
  flutter_bloc: ^7.0.0
  http: ^0.13.1
  meta: ^1.1.6
  equatable: ^2.0.0
  get_it: ^7.1.3
  google_maps_flutter: ^2.0.3
  location: ^4.1.1
  url_launcher: ^6.0.3
  expansion_tile_card: ^2.0.0
  settings_ui: ^1.0.0
  simple_animations: ^3.1.1
  popover: ^0.2.2
  charts_flutter: ^0.10.0
  syncfusion_flutter_charts: ^19.1.64
  sliding_up_panel: ^2.0.0+1
  flutter_speed_dial: ^3.0.5
  flutter_native_splash: ^1.1.8+4
  flutter_launcher_icons: ^0.9.0
  lint: ^1.5.3
  introduction_screen: ^2.1.0
  buy_me_a_coffee_widget: ^2.0.0-nullsafety.0
  material_floating_search_bar: ^0.3.4

dev_dependencies:
  mockito: ^5.0.10
#  test_coverage: ^0.4.2
  bloc_test: ^8.0.0
  flutter_test:
    sdk: flutter

flutter_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/icon/icon.png"

flutter_native_splash:
  color: "#ffffff"
  image: "assets/icon/splash_regular.png"
  color_dark: "#262626"
  image_dark: "assets/icon/splash_dark.png"
  android: true
  ios: true

flutter:
  uses-material-design: true
  assets:
    - assets/images/
    - assets/icon/
    - assets/water/

这是一个权限问题。在 ios/info.plist 中添加以下权限解决了问题:)

<!-- Permission options for the `location` group -->
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Need location when in use</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Always and when in use!</string>
    <key>NSLocationUsageDescription</key>
    <string>Older devices need location.</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Can I have location always?</string>