How to view online 3d assets in flutter ARKit - swift

I'm working on an AR app that fetches 3d assets from a django server and display them using arkit_plugin for flutter.
first I tried passing the link of the model as a url directly, but this didn't work. it showed nothing
node = ARKitReferenceNode(
url: "http://localhost:8000/models/ast.dae",
scale: vector.Vector3.all(0.3),
);
controller.add(node, parentNodeName: anchor.nodeName);
then I tried downloading the model to the documents folder of my iPhone
Future fetchFile(url, fileName) async {
// code for downloading models
final appStorage = await getApplicationDocumentsDirectory();
final file = File(appStorage.path);
final responce = await Dio().get(
url,
options: Options(
responseType: ResponseType.bytes,
followRedirects: false,
receiveTimeout: 0
)
);
final raf = file.openSync(mode: FileMode.write);
raf.writeFromSync(responce.data);
await raf.close();
return file;
}
after that i passed the path of the downloaded model as a url
final appStorage = await getApplicationDocumentsDirectory();
node = ARKitReferenceNode(
url: "${appStorage.path}/modelname.dae",
scale: vector.Vector3.all(0.3),
);
controller.add(node, parentNodeName: anchor.nodeName);
but still didn't work
I also tried loading models from my assets folder of my flutter project, but it still didn't work.
image of my xcode project folder
but after I placed my models in the models.scnassets folder under the Runner folder and passed models.scnassets/dash.dae as a url, it worked, but the problem is I can't view online models in my app. Is there a way to download the models to the models.scnassets folder from the flutter app or other way to solve this problem?
Thanks in advance

Related

Flutter's SharePlus plugin refusing to share images claiming 'The source file doesn't exist'

Flutter's SharePlus plugin is refusing to share images, complaining
PlatformException(Share failed, assets/slideshow/tom_riddle_harry_potter_tour.webp: The source file doesn't exist., null, null)
The source file does exist, it's correctly declared in pubspec.yaml, and displayed in the app elsewhere using Image.asset(... using the same path.
I've tried numerous things, I tried giving XFile the MimeType, that didn't work.
I thought 'maybe it just won't work on web', so I eliminated image sharing in the web app.
Well that got sharing in the web app working, using a fallback, but the problem persisted on Android. So I tried omitting the image's path; just using the file name (with extension). Nope.
I tried specifying the image path string in a different manner, shouldn't work, didn't.
I tried reading the code for XFile and so far as I can see instantiating an XFile using an image path is perfectly valid.
Share.shareXFiles([XFile("assets/slideshow/${presentLocation.pictureList[0]}",
mimeType: "image/webp",
name: presentLocation.name.split(".")[0])],
subject: presentLocation.name + presentLocation.emoji,
text: shareStr,
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size).then((shareResult) async =>
{
if (shareResult.status ==
ShareResultStatus.success)
{
await MyApp.analytics.logShare(
contentType: "URL shared",
itemId: presentLocation.name,
method: "with image")
}
});
Am I misunderstanding XFile? What should I do?
Try this,
var asset = "assets/slideshow/${presentLocation.pictureList[0]}";
ByteData imagebyte = await rootBundle.load(asset);
final temp = await getTemporaryDirectory();
final path = '${temp.path}/temp_image_name.png';
File(path).writeAsBytesSync(imagebyte.buffer.asUint8List());
await Share.shareXFiles(path,
mimeType: "image/webp",
// rest of code
To create temporary directory, path-provider package might be needed if you already don't have it.
https://pub.dev/packages/path_provider

Flutter Web: Show PDF or Any File from Assets on another browser tab or window

Recently, I was working on the portfolio website where I need to show the user's CV which was in the PDF format on another tab.
Since this was a standalone Web Project, I didn't want to handle PDF viewing for iOS and Android.
First, you need to install this package: universal_html
flutter pub add universal_html
import the package in your file
import 'package:universal_html/html.dart' as html;
And here is the method:
Future<void> showCV() async {
var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
}
Voila !
var bytes = await rootBundle.load("assets/files/cv.pdf"); // location of your
asset file
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
Does it work in web hosting also ? because in my case this code is working in local host but not in web host.

How to Overwrite or Update Cache files in Flutter while using Path Provider

Below Code i have created for local caching using path provider
String fileName="pathString.json";
var dir=await getTemporaryDirectory();
File file=File(dir.path+"/"+fileName);
if(!file.existsSync()) {
final http.Response response = await http.get(
Uri.parse("https://*************.herokuapp.com/*********"));
file.writeAsStringSync(
response.body, flush: true, mode: FileMode.write);
final data = file.readAsStringSync();
responseData = json.decode(data);
}else{
final data = file.readAsStringSync();
responseData = json.decode(data);
final http.Response response = await http.get(
Uri.parse("https://**************.herokuapp.com/*********"));
file.writeAsStringSync(
response.body, flush: true, mode: FileMode.write);
}
for first time, File can be Created. But For Second time.. Once File is created, and API fetches latest response with updated data, Cache file not get overwritten.
It would be great, if anyone can help on this..
Thanks in Advance.
i suppose that in your case happening something similar, to my situation:
For flutter Image class i found that, it use ImageCache for caching images, so when you rewrite Image and save it in filesystem, image will look the same until you restart app or invalidate cache.
Code that i wrote for cache invalidation for image:
import 'dart:io';
import 'package:flutter/material.dart';
// imgBytes - raw image bytes here empty just for example
// location - path to image in fs
updateImage(Uint8List imgBytes) async {
var file = File(location);
await file.writeAsBytes(imgBytes, mode: FileMode.write); // rewrite file content
var img = Image.file(file); // create Image class
img.image.evict(); // invalidate cache key for this image
}

How to Share Image from API(URL) in flutter?

Here I want to share image which I get through API. I tried different method for this functionality but I did not get any solution because every solutions have for only one image.
Exactly, I get multiple image from Url and I open any particular image in next page. So, I want to share that image which I opened in another page.
I tried for sharing image but I could not did this. Whenever I try to share that image, Image url share with sharing option on device but I want share image not URl of image How I can accomplish this?
You have to download the image like this:
http.Response response = await http.get(url);
then create an image on the device using the downloaded image like this (Read and Write Files):
final directory = await getTemporaryDirectory();
final path = directory.path;
final file = File('$path/image.png');
file.writeAsBytes(response.bodyBytes);
The getTemporaryDirectory() is in the plugin path_provider. Now, you have the image you'd like to share stored in the temporarily as "image.png" and you can use the share_plus plugin to share the image like this:
Share.shareFiles(['$path/image.png']);
Thanks to #abdulrazak, At first, you have to download the image in a temporary path & then you can share the image as you want. used Dio to download the image & share_plus for sharing
void _shareNetworkImage(String url) async {
Directory tempDir = await getTemporaryDirectory();
final path = '${tempDir.path}/test.jpeg';
await Dio().download(url, path);
Share.shareFiles([path]);
}
You can use the esys_flutter_share plugin.
Install it, and then get dependencies:
dependencies:
esys_flutter_share: ^1.0.2
Import the plugin to your code:
import 'package:esys_flutter_share/esys_flutter_share.dart';
Use the below code:
var request = await HttpClient().getUrl(Uri.parse('https://yourImageURL.jpg'));
var response = await request.close();
Uint8List bytes = await consolidateHttpClientResponseBytes(response);
await Share.file('ESYS AMLOG', 'amlog.jpg', bytes, 'image/jpg');

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good

Looking for a good sample working code for downloading any file from URL in flutter. If its with native downloader then this will be very good. Please help me with sample of code to download any file using native downloader in flutter.
I have used few libraries but didn't turned out well.
For a mobile device, I used the http package to download a file to the applications document directory
First, create a httpClient object
static var httpClient = new HttpClient();
Then you can create a function like this to download the file:
Future<void> _downloadFile({
required String fileName,
}) async {
String url = ...;
var request = await httpClient.getUrl(Uri.parse(url));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory())!.path;
File file = new File('$dir/$fileName'); // Note: Filename must contain the extension of the file too, like pdf, jpg etc.
await file.writeAsBytes(bytes);
}
For a flutter web application, I felt the url_launcher package was the easiest to work with.
_launchURL() async {
String url = ...;
if (await canLaunch(url)) {
await launch(url);
print('URL Launcher success');
} else {
throw Exception('Could not launch $url');
}
}
The url_launcher package code works even for a mobile device but it opens a new browser window to download the required file which is not a good user experience so I have used 2 approaches for the same problem.
Hope I have answered your query.