Swift 4: help decoding a JSON that contains an encoded image using base64 - json

I'm a Swift (and programming) newb, fair warning.
I'm working on an app that is used to track scavenger hunt bonuses. I want to use a JSON file to contain all the bonus data, including a sample image. I see how to encode the image into base64 outside the program, then I can add it into my JSON as a string. Where I'm not certain is what to do with this? From searching I see you would use something like:
class func convertBase64ToImage(imageString: String) -> UIImage {
let imageData = Data(base64Encoded: imageString, options: Data.Base64DecodingOptions.ignoreUnknownCharacters)!
return UIImage(data: imageData)!
}
But I'm not certain if that would simply display said image, or if I need to save that and then call it somehow. The goal is to simply view the image (it is used for reference by the person taking a picture with their placard in the shot).
(I haven't implemented this in code yet, I'm still researching how to do it)

Your code works fine. You can test it out in a Playground easily enough. I used https://www.base64-image.de to Base64 encode a small PNG file and generate a string which I ran through your function. It worked fine.
To answer your direct question, UIImage is simply an image which you can display to the user as follows:
Create a view controller. Add a UIImageView to the view controller and wire up an outlet for it with a suitable name (for example, bonusImageView).
Call your function within the view controller to load the image into the image view.
bonusImageView.image = convertBase64ToImage(imageString: imageString)
Where imageString is the Base64-encoded string you obtained from your JSON.
Whether or not you choose to store the imageString first is up to you. It's not necessary to store it if all you want to do is retrieve it from a server and display it on demand.

Related

How can I put this "\/\/cdn.apixu.com\/weather\/64x64\/day\/116.png" inside of a String, I have a problem with the "\/\/"

I'm trying to put "-\/\/- Some URL for image"
inside of a string but I have a problem with the "-\/\/-", somebody can help me with that?
This looks like you're getting an image URL in a JSON response, which contains a property similar to this:
{
"imageUrl": "\/\/cdn.apixu.com\/weather\/64x64\/day\/116.png"
}
Don't worry about the backslash-escaped / characters, that's just an artifact of the JSON encoding, and any JSON parser you use on iOS will remove those, yielding a String value of
//cdn.apixu.com/weather/64x64/day/116.png
Now, a URL starting with just // is called a protocol-relative URL, so you'll have to prepend whatever protocol you used to get the initial JSON response, most likely https:. This gives you
https://cdn.apixu.com/weather/64x64/day/116.png
which indeed is a 64x64 pixel image that you can download and display in your app:

get dynamically loaded html using alamofire + swift

I am trying to request a website's html code and use it in an app in Xcode (Swift 3.0) and the pod Alamofire. In the html code online, the data contents that I want to scrape are in a div class that returns data from an Events calendar, in the form of a javascript web plugin. Since the website is not static, when I request the html and print the resulting response as a string, the data I want is not contained in the string. A message appears that says:
<noscript>Your browser must support JavaScript to view this content.
Please enable JavaScript in your browser settings then try again.
Events calendar powered by Trumba
</noscript>
My code using Alamofire looks like:
func downloadCalendar(){
Alamofire.request(urlString).responseString { (AlamofireResponse) in
print(AlamofireResponse.result.value!)
}
}
The urlString is a variable for the actual webpage's url.
Is there a way to get all of the html that appears in the html online into Xcode using Alamofire? If it's not possible with Alamofire is there another way to do this using Swift?
I've tried to accomplish a similar thing, unfortunately to no avail...
It seams AlamoFire grabs the first response it gets....
There is a workaround - use UIWebView:
static let webView = UIWebView()
self.webView.loadRequest(URLRequest.init(url: URL.init(string:"http://example.com")!)
DispatchQueue.main.asyncAfter(deadline: .now()+10.0) {[unowned self] in
if let html = self.webView.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML")
{print(html)}
}
Where 10.0 is the approx number of seconds required for javascript to finish loading the webpage data.
However since: it's not thread safe, you must use a singleton webView,
import UIKit and can't do it in the background - it's far from the perfect solution...
It might be easier to setup a proxy webserver in between to do the parsing for you.
Cheers!

Referencing images stored in object storage containers (Wirecloud) from img tag

We want to develop a widget to upload images to containers. This is a very well documented task:
1.- Object Storage Tutorial
2.- Fireware-Wiki
3.- OpenStack Object Storage Docs (Swift)
With all this you can manage to get (download), upload, delete files in a container. This is relatively clear.
On the other hand, we want to develop another widget to display images stored in a container. I think in something like this to show them:
<img src="public_object_url"/>
But I do not know how to do that. Where I get this public URL? Is there a public URL? Is it get in some step during the uploading process?
I am a bit lost how to do that. Any help would be highly appreciated.
Thanks in advance.
EDIT 1
We get blocked displaying images once they are downloaded.
A look inside "img" tags shows this:
what is the string returned by URL.createObjectURL(). If we look inside this link, the browser displays this:
We have decoded the string coming in the property "value" and the image is there!
To get the image from the object storage server we used a very similar code that the one used in the operator Álvaro recommended.
objectstorage.getFile( containerName,
reports[i].urlImagen,{
token: token,
onSuccess: onGetFileSuccess.bind(null, i),
onFailure: onGetFileFailure
});
function onGetFileSuccess(index, picture){
downloadedPicsCont--;
reports[index].urlImagen = URL.createObjectURL(picture);
if(!(downloadedPicsCont > 0)){
MashupPlatform.wiring.pushEvent('reports_output', JSON.stringify(reports));
}
}
The picture variable has the following structure, which seems to be ok too.
What is it happening?
EDIT 2
Finally, we found the reason. We were downloading images that were created directly from the cloud and not with objectStorageAPI. In you upload images from the cloud, when you download them you get them inside cdmi objects so the URL.createObjectURL doesn't not work as expected. In the other hand, if you upload them using objectStorageAPI, when downloading them, they come in raw format, so the method works correctly.
As far as I know, FIWARE Object Storage needs authentication, so there are no such public URL. But... you can download the image using your credentials and then use the URL.createObjectURL method for getting an URL usable in the src attribute of the img element.
It's a bit old, but you can use this operator as reference.

How to display images from an email with QWebView?

I have an email which contains perfectly formatted html with the single exception that images are linked differently: <img width=456 height=384 id="_x0000_i1026" src="cid:X.MA2.1374935634#aol.com" alt="cid:X.MA4.1372453963#aol.com"> the email has other parts including the image with this content id. The problem is that I dont know how to point the QWebview to the data (which I have). Is there a way to add the image to its cache?
It's possible but not easy.
Basically you need to:
1- provide your own QNetworkAccessManager-inherited class, overriding createRequest() to catch these links refering to "cid":
QNetworkReply*
MyManager::createRequest (Operation op,
const QNetworkRequest & req,
QIODevice * outgoingData = 0)
{
if (op==GetOperation && req.url().scheme() == "cid")
return MyNetworkReply(req.url().path());
else
return QNetworkAccessManager::createRequest(op, req, outgoingData);
}
2- Connect it to the webview with:
MyManager* manager = new MyManager;
view->page()->setNetworkAccessManager(manager);
3- Provide an implementation of MyNetworkReply which inherits from QNetworkReply, a QIODevice-class. And this is the complicated part. You need to provide at least readData(), bytesAvailable(), a constructor that sets up the reply in terms of HTTP headers, and launches the actual asynchronous read with QTimer::singleShot()
4- Decode the attachment (probably from base64 if it's a picture) into a QByteArray for your MyNetworkReply::readData() to read from that.
There's a complete example on qt.gitorious.org written by Qt Labs developers in the Qt 4.6 days. They display an internally generated PNG, not an external mail attachment, but the general steps are as described above. See:
http://qt.gitorious.org/qt-labs/graphics-dojo/blobs/master/url-rendering/main.cpp
However this code has a flaw with Qt-4.8. in the constructor for RendererReply, when it does:
open(ReadOnly|Unbuffered);
this should be:
open(ReadOnly);
otherwise webkit never reads the entire data and displays the broken picture icon.

How do you display image from "image_url" in Yelp API?

I now understand how to parse and display JSON data, but one thing eludes me: when I call "image_url" and receive the actual URL, how can I instead display the image that it refers to? ...and yes, I am a novice :)
Thanks!
You can do that like this:
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:theUrl]]];
where theUrl is the url in string format. Then simply assign the image to your image view: imageView.image = image - presuming you have set up a UIImageView either in your code, as an IBOutlet or as a tagged object in a view.
NOTE: You may want to have a look at Lazy Table Images to load the image asynchronously.