Skip to content

Commit f7f6e16

Browse files
authored
fixed deeplink docs (#502)
1 parent d13a2b5 commit f7f6e16

File tree

1 file changed

+55
-76
lines changed

1 file changed

+55
-76
lines changed

docusaurus/docs/Flutter/05-advanced/01-deeplinking.mdx

Lines changed: 55 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ To handle deep links in Android you need to declare an intent filter in `android
1414
<activity
1515
android:name=".MainActivity"
1616
android:exported="true">
17-
<intent-filter
18-
android:autoVerify="true"
19-
android:label="Call Link">
17+
<intent-filter android:autoVerify="true" android:label="call_link">
2018
<action android:name="android.intent.action.VIEW" />
21-
2219
<category android:name="android.intent.category.DEFAULT" />
2320
<category android:name="android.intent.category.BROWSABLE" />
2421
<data
@@ -101,9 +98,11 @@ In its simplest form, your AASA file should have the following format:
10198
}
10299
```
103100

104-
You can also specify exact paths if you want to have stricter control over which ones can invoke your app. You can also specify several apps on the same domain.
101+
You can also specify exact paths if you want to have stricter control over which ones can invoke your app.
102+
You can also specify several apps on the same domain.
105103

106-
Before proceeding, please make sure that the uploaded file is a valid one, and it's deployed at the right place. For this, you can use Apple's [validation tool](https://search.developer.apple.com/appsearch-validation-tool).
104+
Before proceeding, please make sure that the uploaded file is a valid one, and it's deployed at the right place.
105+
For this, you can use Apple's [validation tool](https://search.developer.apple.com/appsearch-validation-tool).
107106

108107
## Handling deep links
109108

@@ -118,52 +117,61 @@ dependencies:
118117
Next, use the snippet below to listen for incoming deep links and navigate to `JoinScreen` that we'll cover in the next step:
119118

120119
```dart
120+
import 'package:uni_links/uni_links.dart';
121+
122+
StreamSubscription<Uri?>? _deepLinkSubscription;
123+
121124
Future<void> _observeDeepLinks() async {
122-
// 1
125+
// The app was in the background.
126+
if (!kIsWeb) {
127+
_deepLinkSubscription = uriLinkStream.listen((uri) {
128+
if (mounted && uri != null) _handleDeepLink(uri);
129+
});
130+
}
131+
132+
// The app was terminated.
123133
try {
124134
final initialUri = await getInitialUri();
125-
if (initialUri != null) {
126-
await _handleDeepLink(initialUri);
127-
}
135+
if (initialUri != null) _handleDeepLink(initialUri);
128136
} catch (e) {
129137
debugPrint(e.toString());
130138
}
131-
132-
// 2
133-
if (!kIsWeb) {
134-
_subscription = uriLinkStream.listen((Uri? uri) {
135-
if (mounted && uri != null) {
136-
_handleDeepLink(uri);
137-
}
138-
});
139-
}
140139
}
141140
142141
Future<void> _handleDeepLink(Uri uri) async {
143-
// 3
144-
final callId = uri.pathSegments.last;
145-
146-
// 4
147-
Navigator.of(context).push(
148-
MaterialPageRoute(
149-
builder: (context) {
150-
return JoinScreen(
151-
callId: callId,
152-
);
153-
},
154-
),
155-
);
142+
// Parse the call id from the deep link.
143+
final callId = uri.queryParameters['id'];
144+
if (callId == null) return;
145+
146+
// return if the video user is not yet logged in.
147+
// Replace the getCurrentUser() method with your method to retrieve the current user
148+
final currentUser = getCurrentUser();
149+
if (currentUser == null) return;
150+
151+
final streamVideo = StreamVideo.instance;
152+
final call = streamVideo.makeCall(type: kCallType, id: callId);
153+
154+
try {
155+
await call.getOrCreate();
156+
} catch (e, stk) {
157+
debugPrint('Error joining or creating call: $e');
158+
debugPrint(stk.toString());
159+
return;
160+
}
161+
162+
// Your method to navigate to the lobby/call screen.
163+
navigateToCallScreen();
156164
}
157165
```
158166

159167
In this snippet, you:
160168

161-
1. Handle the case when the app was terminated and is now started by a deep link.
162-
2. Handle the case when the app was in the background and is now brought to the foreground by a deep link.
169+
1. Handle the case when the app was in the background and is now brought to the foreground by a deep link.
170+
2. Handle the case when the app was terminated and is now started by a deep link.
163171
3. Extract the call ID from the deep link URL.
164-
4. Navigate to a screen that will handle call initialization.
172+
4. Navigate to a screen that will handle the call.
165173

166-
Finally, add `JoinScreen` with the call initialization:
174+
While you can initialize the call on your call screen, you can also add an intermediary `JoinScreen` with the call initialization:
167175

168176
```dart
169177
class JoinScreen extends StatefulWidget {
@@ -184,9 +192,10 @@ class _JoinScreenState extends State<JoinScreen> {
184192
@override
185193
void initState() {
186194
super.initState();
187-
_initCall(widget.callId);
195+
_joinCall(widget.callId);
188196
}
189197
198+
// Step 1
190199
@override
191200
Widget build(BuildContext context) {
192201
return Scaffold(
@@ -196,45 +205,25 @@ class _JoinScreenState extends State<JoinScreen> {
196205
body: Center(
197206
child: _isInProgress
198207
? const CircularProgressIndicator(
199-
strokeWidth: 2,
200-
)
208+
strokeWidth: 2,
209+
)
201210
: const SizedBox(),
202211
),
203212
);
204213
}
205214
206-
Future<void> _initCall(String callId) async {
207-
await _logIn();
208-
await _joinCall(widget.callId);
209-
}
210-
211-
// 1
212-
Future<void> _logIn() async {
213-
final userCredentials = await UserRepository.instance.getUserCredentials();
214-
215-
if (userCredentials != null) {
216-
final user = userCredentials.user;
217-
final token = userCredentials.token;
218-
219-
await StreamVideo.instance.connectUser(
220-
user,
221-
token: Token(token),
222-
);
223-
}
224-
}
225-
226-
// 2
215+
// Step 2
227216
Future<void> _joinCall(String callId) async {
228217
setState(() => _isInProgress = true);
229218
230219
try {
231-
final call = await StreamVideo.instance.joinCall(
220+
final call = StreamVideo.instance.makeCall(
232221
id: callId,
233222
type: 'default',
234223
);
235224
236225
await call.join();
237-
226+
238227
await _navigateToCall(call);
239228
} catch (e) {
240229
debugPrint(e.toString());
@@ -243,28 +232,18 @@ class _JoinScreenState extends State<JoinScreen> {
243232
}
244233
}
245234
246-
// 3
235+
// Step 3
247236
Future<void> _navigateToCall(Call call) async {
248-
await Navigator.of(context).push(
249-
MaterialPageRoute(
250-
builder: (context) {
251-
return StreamCallScreen(
252-
call: call,
253-
onBackPressed: navigateHome,
254-
onHangUp: navigateHome,
255-
);
256-
},
257-
),
258-
);
237+
// Navigate to your call screen
259238
}
260239
}
261240
```
262241

263242
Here's what you're doing here, step-by-step:
264243

265-
1. Connecting the user from your persistence storage to the Video API.
244+
1. Showing a connecting screen for the call while it initializes.
266245
2. Joining the call with the call ID from the deep link.
267-
3. Navigating to `StreamCallScreen` from our SDK.
246+
3. Navigating to your call screen.
268247

269248
## Testing deep links
270249

0 commit comments

Comments
 (0)