diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index c691a0484f2..1f193db5cb0 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -55,6 +55,8 @@ TODO: Remove this section if there are not any general updates. - Added more informative dialog if Deep Links tool is unable to find build options for the iOS or Android app. - [#9571](https://github.com/flutter/devtools/pull/9571) +- Fixed null error when parsing universal link settings - + [#9581](https://github.com/flutter/devtools/pull/9581) ## VS Code Sidebar updates diff --git a/packages/devtools_shared/lib/src/deeplink/universal_link_settings.dart b/packages/devtools_shared/lib/src/deeplink/universal_link_settings.dart index 486b09a74a8..0cc78b5a96a 100644 --- a/packages/devtools_shared/lib/src/deeplink/universal_link_settings.dart +++ b/packages/devtools_shared/lib/src/deeplink/universal_link_settings.dart @@ -21,10 +21,10 @@ extension type const UniversalLinkSettings._(Map _json) { }); /// The bundle identifier of the iOS build of this Flutter project. - String get bundleIdentifier => _json[_kBundleIdentifierKey] as String; + String? get bundleIdentifier => _json[_kBundleIdentifierKey] as String?; /// The team identifier of the iOS build of this Flutter project. - String get teamIdentifier => _json[_kTeamIdentifierKey] as String; + String? get teamIdentifier => _json[_kTeamIdentifierKey] as String?; /// The associated domains of the iOS build of this Flutter project. List get associatedDomains => diff --git a/packages/devtools_shared/test/deeplink/universal_link_settings_test.dart b/packages/devtools_shared/test/deeplink/universal_link_settings_test.dart new file mode 100644 index 00000000000..15a56adb54c --- /dev/null +++ b/packages/devtools_shared/test/deeplink/universal_link_settings_test.dart @@ -0,0 +1,50 @@ +// Copyright 2025 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd. + +import 'package:devtools_shared/src/deeplink/universal_link_settings.dart'; +import 'package:test/test.dart'; + +void main() { + group('UniversalLinkSettings', () { + test('parses json correctly', () { + const json = ''' +{ + "bundleIdentifier": "com.example.app", + "teamIdentifier": "TEAMID", + "associatedDomains": ["applinks:example.com"] +} +'''; + final settings = UniversalLinkSettings.fromJson(json); + expect(settings.bundleIdentifier, 'com.example.app'); + expect(settings.teamIdentifier, 'TEAMID'); + expect(settings.associatedDomains, ['applinks:example.com']); + }); + + test('handles null bundleIdentifier', () { + const json = ''' +{ + "teamIdentifier": "TEAMID", + "associatedDomains": ["applinks:example.com"] +} +'''; + final settings = UniversalLinkSettings.fromJson(json); + expect(settings.bundleIdentifier, isNull); + expect(settings.teamIdentifier, 'TEAMID'); + expect(settings.associatedDomains, ['applinks:example.com']); + }); + + test('handles null teamIdentifier', () { + const json = ''' +{ + "bundleIdentifier": "com.example.app", + "associatedDomains": ["applinks:example.com"] +} +'''; + final settings = UniversalLinkSettings.fromJson(json); + expect(settings.bundleIdentifier, 'com.example.app'); + expect(settings.teamIdentifier, isNull); + expect(settings.associatedDomains, ['applinks:example.com']); + }); + }); +}