How to read a blob data URL in WKWebView? - xcode

I have a WKWebView, but when I click on a link that has the following URL:
blob:https://www.mycase.com/2963c6c0-24c1-418f-a314-88f7a2dbc713
Nothing happens. Reading the documentation it describes:
The only way to read content from a Blob is to use a FileReader.
So I presume there is no way WKWebView is able to read the Blob itself by some method. As URLSession fails to download the content when you feed it the blob URL.
A solution I came up with myself is to read the blob in JavaScript itself.
var script = ""
script = script + "var xhr = new XMLHttpRequest();"
script = script + "xhr.open('GET', '\(navigationURL)', true);"
script = script + "xhr.responseType = 'blob';"
script = script + "xhr.onload = function(e) { if (this.status == 200) { var blob = this.response; var reader = new window.FileReader(); reader.readAsBinaryString(blob); reader.onloadend = function() { window.webkit.messageHandlers.readBlob.postMessage(reader.result); }}};"
script = script + "xhr.send();"
self.webView.evaluateJavaScript(script, completionHandler: nil);
Then add a script message handler to fetch the content.
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(self, name: "readBlob")
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print(message.body)
}
It feels a bit cumbersome to do it like this, is there any other way?

Related

google sheets apps script

I wanted to ask I have a few lines of code. And until yesterday, everything worked perfectly for me.
Now when I start debugging the script, it ends up with an error message on line 24 => var ui = SpreadsheetApp.getUi();.
Exception: Cannot call SpreadsheetApp.getUi() from this context.
inputBox # ulozDataDoDb.gs:24
But when I run this script from the button in the google sheet, it works.
Does anyone know what to do with it?
function inputBox() {
//definice aktivního sešitu
var ss = SpreadsheetApp.getActive();
//definice aktivního listu
var faktura = ss.getSheetByName("faktura");
var dataBaze = ss.getSheetByName("db");
//definice promenných pro dalši práci
var cisloFaktury = faktura.getRange("I3").getValue();
var varSymbol = faktura.getRange("E22").getValue();
var datumVystaveni = faktura.getRange("datumVystaveni").getValue();
var prijmeni = faktura.getRange("prijmeni").getValue();
var jmeno = faktura.getRange("jmeno").getValue();
var prijmeniJmeno = jmeno + " " + prijmeni;
var castka = faktura.getRange("I55").getValue();
var konstSymb = faktura.getRange("E23").getValue();
var specSymb = faktura.getRange("E24").getValue();
var formaUhrady = faktura.getRange("E19").getValue();
//zapsat do DB
//popis do DB
var ui = SpreadsheetApp.getUi();
var popis_v_DB = ui.prompt("Zadejte název do DB.").getResponseText();
popis_v_DB = popis_v_DB.split(" ").join("_"); //vyhledá mezery a nahradí znakem
The Cannot call SpreadsheetApp.getUi() from this context. exception you are receiving is due to the fact that that prompt has to be actioned on by a user and not by a script.
According to the documentation:
prompt(prompt) - Will open an input dialog box in the user's editor with the given message and an "OK" button. This method suspends the server-side script while the dialog is open. The script resumes after the user dismisses the dialog.
Reference
Apps Script Ui Class - prompt().
Try to replace
var ui = SpreadsheetApp.getUi();
var popis_v_DB = ui.prompt("Zadejte název do DB.").getResponseText();
by
var popis_v_DB = Browser.inputBox("Informace.", "Zadejte název do DB.", Browser.Buttons.OK_CANCEL);
but as far as you ask somebody to enter a value, you will do it by the sheet not by the script editor !

receive file in my xamarin app from another's app share function

How to receive file in my xamarin app from another's app share function?
if (Intent.Action == Intent.ActionSend)
{
{
// This is just an example of the data stored in the extras
var uriFromExtras = Intent.GetParcelableExtra(Intent.ExtraStream) asAndroid.Net.Uri;
var subject = Intent.GetStringExtra(Intent.ExtraSubject);
// Get the info from ClipData
var pdf = Intent.ClipData.GetItemAt(0);
// Open a stream from the URI
var pdfStream = ContentResolver.OpenInputStream(pdf.Uri);
// Save it over
var memOfPdf = new System.IO.MemoryStream();
pdfStream.CopyTo(memOfPdf);
var docsPath = System.Environment.GetFolderPat(System.Environment.SpecialFolder.Personal);
var filePath = System.IO.Path.Combine(docsPath, "temp.pdf");
System.IO.File.WriteAllBytes(filePath, memOfPdf.ToArray());
mainForms.DisplayThePDF(filePath);
}
}
this is only for PDF and also not working well.

Save POST response as file in NativeScript

In my NativeScript-Vue app, I make a POST request to my server and receive a binary file. It's a .zip file containing a .db file which I want to copy and initialize with the nativescript-sqlite plugin.
I am using axios and the POST response looks like this:
"PK {[oP'g�R 606.db�}`�����ו�N�-{�*�*�O炵W$�滓\(��t�KZ��dc2�e�C�Ĕ$�L
>b!��... and so on
Right now I am testing on Android. I am saving the file to the Android Downloads folder to see if I can unzip it. I know that File.write accepts a native byte array, so I am trying to get one from the binary file string.
import * as fs from "tns-core-modules/file-system";
async function saveToFile(binary) { // binary = "PK {[oP'g�R...
let folder = fs.Folder.fromPath(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath());
let zipFile = folder.getFile("Database.zip");
// string to buffer
let buffer = new ArrayBuffer(binary.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < view.length; i++) {
view[i] = binary.charCodeAt(i);
}
// buffer to native byte array
let array = Array.create("byte", view.byteLength);
for (let i = 0; i < view.byteLength; i++) {
array[i] = new java.lang.Byte(view[i]);
}
await zipFile.write(array);
}
I think I am doing things wrong, cycling arrays two times, anyway I am able to write the file but I can't open it as a .zip. Any help?
Solved switching from axios to NativeScript HTTP module, handling directly a File object instead of a string.
import { getFile } from "tns-core-modules/http";
import { Zip } from "nativescript-zip";
async function saveDatabaseToFile() {
let folder = fs.knownFolders.temp();
let zipFile = await getFile({
method: "POST", // url, headers, content
});
await file.rename("Database.zip"); // extension was messed up
await Zip.unzip({
archive: file.path,
directory: folder.path
});
let files = await folder.getEntities();
let dbFile = files.find(file => file._extension === ".db");
return dbFile;
}

Parse Server S3 Adaptor saves image as .txt

I am using the S3 adaptor to save images to my S3 bucket. My client code is:
var saveFileToParse = function(imageData) {
var parseFile = new Parse.File(Parse.User.current().id + " Image", {
base64: imageData
});
$ionicLoading.show();
parseFile.save().then(function(response) {
if (angular.isNumber($scope.activeExercise.images[0])) {
$scope.activeExercise.images = [];
}
var imageUrl = response._url;
$scope.activeExercise.images.push(imageUrl);
$scope.$apply();
$scope.customImage = true;
$ionicLoading.hide();
}).then(function(imageUrl) {
var file = new Parse.Object("Files");
file.set("file", parseFile);
file.save().then(function(response) {
$ionicLoading.hide();
});
},
function(error) {
$ionicLoading.hide();
errorFactory.checkError(error);
});
};
The file is being saved, however is being saved as a .txt file, I expect because of the base 64, however this was never an issue on parse.com. Can I explicitly make this save as .jpg?
EDIT:
I am employed the code below and this gives a different filename and shows as an image in S3. However, when downloaded it still has a .txt file extension. I have even changed my save command to include the mime-type var parseFile = new Parse.File(name, file, "image/jpeg");
The issue here was caused by the old parse.com server automatically applying %20 when there was a space in the file URL.
Removing the space made it work.
Honestly, you just need to read the documentation thoroughly. The answer is already available there, so just pass the file object.
var fileUploadControl = $("#profilePhotoFileUpload")[0];
if (fileUploadControl.files.length > 0) {
var file = fileUploadControl.files[0];
var name = "photo.jpg";
var parseFile = new Parse.File(name, file);
parseFile.save().then(function () {
// The file has been saved to Parse.
}, function (error) {
// The file either could not be read, or could not be saved to Parse.
});
}

Node.js proxy, dealing with gzip DEcompression

I'm currently working on a proxy server where we in this case have to modify the data (by using regexp) that we push through it.
In most cases it works fine except for websites that use gzip as content-encoding (I think), I've come across a module called compress and tried to push the chunks that I receive through a decompress / gunzip stream but it isn't really turning out as I expected. (see below for code)
figured i'd post some code to support my prob, this is the proxy that gets loaded with mvc (express):
module.exports = {
index: function(request, response){
var iframe_url = "www.nu.nl"; // site with gzip encoding
var http = require('http');
var httpClient = http.createClient(80, iframe_url);
var headers = request.headers;
headers.host = iframe_url;
var remoteRequest = httpClient.request(request.method, request.url, headers);
request.on('data', function(chunk) {
remoteRequest.write(chunk);
});
request.on('end', function() {
remoteRequest.end();
});
remoteRequest.on('response', function (remoteResponse){
var body_regexp = new RegExp("<head>"); // regex to find first head tag
var href_regexp = new RegExp('\<a href="(.*)"', 'g'); // regex to find hrefs
response.writeHead(remoteResponse.statusCode, remoteResponse.headers);
remoteResponse.on('data', function (chunk) {
var body = doDecompress(new compress.GunzipStream(), chunk);
body = body.replace(body_regexp, "<head><base href=\"http://"+ iframe_url +"/\">");
body = body.replace(href_regexp, '<a href="#" onclick="javascript:return false;"');
response.write(body, 'binary');
});
remoteResponse.on('end', function() {
response.end();
});
});
}
};
at the var body part i want to read the body and for example in this case remove all hrefs by replacing them with an #. The problem here of course is when we have an site which is gzip encoded/ compressed it's all jibberish and we can't apply the regexps.
now I've already tired to mess around with the node-compress module:
doDecompress(new compress.GunzipStream(), chunk);
which refers to
function doDecompress(decompressor, input) {
var d1 = input.substr(0, 25);
var d2 = input.substr(25);
sys.puts('Making decompression requests...');
var output = '';
decompressor.setInputEncoding('binary');
decompressor.setEncoding('utf8');
decompressor.addListener('data', function(data) {
output += data;
}).addListener('error', function(err) {
throw err;
}).addListener('end', function() {
sys.puts('Decompressed length: ' + output.length);
sys.puts('Raw data: ' + output);
});
decompressor.write(d1);
decompressor.write(d2);
decompressor.close();
sys.puts('Requests done.');
}
But it fails on it since the chunk input is an object, so i tried supplying it as an chunk.toString() which also fails with invalid input data.
I was wondering if I am at all heading in the right direction?
The decompressor expects binary encoded input. The chunk that your response receives is an instance of Buffer which toString() method does by default give you an UTF-8 encoded string back.
So you have to use chunk.toString('binary') to make it work, this can also be seen in the demo.

Resources