Note: This post was originally published on Medium. Rene Pot is an Appcelerator Titan, long time member of the Titanium community, and runs the Slack Titanium Channel @Ti_Slack. For more, you can follow him on Medium and Twitter.
It is really easy to include images in your app. Just add an ImageView to your View and add the URL and you’re done.
<ImageView id="mainImage" image="https://example.com/image.png" />
While you’re developing the app, and the backend of your app evolves the need arises to secure the system. Images are no longer public and they need to be fetched using oAuth tokens. So what do you, rewrite the entire app to be able to fetch images?
In fact, you can change it easily with minimal effort and hardly any impact on your code. But it will require you to not use the ListView
component, as ListViews have no extend support.
Extending Alloy
The answer to this problem is in Alloy Extending. There is a property you can use in your Alloy View called module
. Within your Views, this is the only change you need to do.
<ImageView module="authImage" id="mainImage"
image="https://example.com/image.png" />
As you can see, I added module="authImage"
. What this does is it looks for a commonjs/module/widget inside your app. Under the hood it behaves like require('authImage')
. In fact, because I use ImageView
here, the exact code this translates to is: require('authImage').createImageView(args)
.
As you can see, this gives a great opportunity to add logic to ImageViews. I will guide you through the creation of the module, or in this case a commonjs
file from the lib
folder.
Note: This solution is only possible with Alloy
Creating authImage lib
As discussed above, Alloy is looking for a createImageView
function inside the authImage lib. So the basic thing the lib needs to do is have a function called createImageView and that function should return an ImageView. Your file (/app/lib/authImage.js
) should look something like this:
function createImageView(args){
var igvm = Ti.UI.createImageView(args);
return igvm;
}
module.exports = {
createImageView: createImageView
};
This basic example basically overrides your createImageView
method and makes it possible for you to extend. Every property you set in tss
or xml
file regarding the ImageView
will be inside the args
variable. For instance, the url to the image.
From now, you will need to intercept the image and insert it later. For this you need to create a function inside the lib that initiates an XHR call with the token as a requestheader. You can probably hook it up to the flow you probably already have internally, or create a small http call inside the lib file (I recommend the first).
As the code immediately becomes a lot longer, I’ve open sourced my code that does an API call and stores the file in the temp directory in your app. You can see the related code here: https://github.com/Topener/authenticatedImageView/blob/master/lib/authImage.js
The entire repository is dedicated to downloading images and storing them. Just have a proper look at the code in this repository and you can see how easy it is to download images like this.
Extending it even further
You’ve now touched the first base of extending Alloy elements using the module
tag. It can be quite powerful. For example, you could resize images to square inside your lib
file, or rotate them, or change colors, or do more awesome things. You could even add a button on top of the ImageView with an example like this:
function createImageView(args){
var wrapperView = Ti.UI.createView({height: Ti.UI.SIZE, width: Ti.UI.SIZE});
wrapperView.add(Ti.UI.createImageView(args));
wrapperView.add(Ti.UI.createButton({width: 50, height: 50, bottom: 10, right: 10, title: '?'}));
return wrapperView;
}
You get the point, everything is possible. I’m curious what you come up with.
Meetup
This blogpost originates from a TitaniumNL meetup where I discussed this exact topic.
Follow us on social