# Communication between Wikitude and Flutter
- Creating an AR experience is one thing, but we need a way to interact between the Flutter app and the Wikitude AR experience
- For example: scanning a wine label and giving a rating should result in saving this rating through the api in our app
- Interaction/communication is needed between Wikitude and Flutter!
- We will discuss communication in the two directions from Wikitude to Flutter and from Flutter to Wikitude.
# From Wikitude to Flutter
- We start with the communication you will probably need most: from Wikitude to Flutter
# Send a message from Wikitude
- Let's say we want to navigate to a specific page in our Flutter app after we scanned an image:
- maybe a page with a form to submit your answer to a question
- or a page to show some detailed information about the product
- ...
- In our Wikitude part (JavaScript code) we can send back a JSON object to Flutter:
this.quizTrackable = new AR.ImageTrackable(this.tracker, "*", {
onImageRecognized: function(target) {
//alert(target.name);
//send back image name, so we can navigate to page and ask question
AR.platform.sendJSONObject({
"image_scanned" : target.name
});
World.hideInfoBar();
},
onError: World.onError
);
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- In this example we send back a JSON object with 1 property
image_scanned
. The value for this property is the name of the recognized image
# Model class in Flutter
- Now you need a model class in Flutter in which you can receive the JSON object from your JavaScript-code.
- Since there's only one property
image_scanned
this class is rather small. Of course you can extend this class if necessary
class ARImageResponse {
String imageScanned;
ARImageResponse({required this.imageScanned});
factory ARImageResponse.fromJson(Map<String, dynamic> json) {
return ARImageResponse(
imageScanned: json['image_scanned'],
);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Receive the message in Flutter
- To receive the JSON object we need to register the callback on our
ArchitectWidget
instance:
Future<void> onArchitectWidgetCreated() async {
architectWidget.load(
"samples/01_ImageTracking_1_ImageOnTarget/index.html",
onLoadSuccess,
onLoadFailed);
architectWidget.resume();
architectWidget.setJSONObjectReceivedCallback(
(result) => onJSONObjectReceived(result));
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- In the callback method
onJSONObjectReceived
we can interpret the JSON object using thefromJson
method in theARImageResponse
class from above and perform one or more actions. - In the code below (as an example) we fetch a question via an api-call based on the scanned image and navigate to a
QuestionPage
passing theid
of the question
void onJSONObjectReceived(Map<String, dynamic> jsonObject) async {
var imageScanned = ARImageResponse.fromJson(jsonObject);
//get question and navigate to question/answer page
QuestionsApi.fetchQuestionByImageName(imageScanned.imageScanned)
.then((result) {
if (result != null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => QuestionPage(id: result.id)),
);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- Now you've got all the building blocks to interact from within your AR experience with your Flutter application
# From Flutter to Wikitude
- As promised, we will also explain the other way around: from Flutter to Wikitude
- As an example we will use our dino app and try to pass an
id
from our Flutter Dart app (armultipletargets.dart
) to the Wikitude Javascript AR experience (multiplesimultaneoustargets.js
)
# Receive the id in Wikitude
- Open
multiplesimultaneoustargets.js
and add a new variableid
in theWord
:
var World = {
id: 0,
loaded: false,
...
1
2
3
4
2
3
4
- Next add a new function
newData
at the end of theWorld
. We will use this function to pass thenewId
from our Flutter app to Wikitude:
...
showInfoBar: function worldLoadedFn() {
document.getElementById("infoBox").style.display = "table";
document.getElementById("loadingMessage").style.display = "none";
},
newData: function newDataFn(newId) {
World.id = newId;
document.getElementById("text").innerHTML = World.id.toString();
}
};
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- As you can see in the code block above, we will show the
Word.id
in the banner when Wikitude is started. Therefore modifyindex.html
and add an id-attribute to the div-tag:
<div id="infoBox" class="info">
<div class="text" id="text">Scan one of the dinosaur targets:</div>
<div class="icons">
<img src='assets/diplodocus.png'/>
<img src='assets/spinosaurus.png'/>
<img src='assets/triceratops.png'/>
<img src='assets/tyrannosaurus.png'/>
</div>
</div>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# Send the id in Flutter
- As a final step, we will call the
newData
function fromarmultipletargets.dart
and pass thenewId
parameter (as an example we'll use a harcoded 911). Inarmultipletargets.dart
add the line below to theonLoadSuccess()
method:
Future<void> onLoadSuccess() async {
debugPrint("Successfully loaded Architect World");
architectWidget.callJavascript('World.newData(911)');
}
1
2
3
4
2
3
4
- Run your app and check if the number 911 appears when scanning in Wikitude: