Start off by heading over to the React Native Getting Started page. They offer two options: Quick Start and Building Projects with Native Code. I have not tried the, now default, Quick Start option. Several documentation pages refer to needing to “eject” your application if it was created from the Quick Start. For that reason alone I have only used the Building Projects with Native Code option.
There are a few dependencies to install, but the guide walks you through what you need. You will need NodeJS and the watchman package for observing changes. You will also need to install the react native cli. Additionally, you will need Xcode if building for iOS and Android Studio if building for Android.
Once you’ve got the dependencies installed you create a new project with the CLI:
react-native init AwesomeProject
Running the App
With no changes to the code base, you can immediately build the app you just created. In a Titanium project, all builds are handled through the Axway Appcelerator CLI or Axway Appcelerator Studio. This is not the case with React. It seems you can only build to an iOS simulator, Android emulator, or Android device with the React Native CLI. To do this you use either:
To target iOS simulator. Or:
To target an Android device or emulator.
The options provided with these commands are a little lacking compared to the options with the Axway Appcelerator CLI. In my time with React Native, every simulator build chose the iPhone 6 simulator. I could not find an option to specify a different simulator with the CLI. Additionally, the CLI does not handle multiple connected Android devices well. You need to only have a single connected Android device or running emulator.
So how do you target other iOS simulators or build to an iOS device? Open Xcode! From there you use the same build options that a native developer would use. This is a huge difference from Titanium that basically discourages the use of Xcode for anything but building native modules. If you’ve never done native iOS development this can be a little daunting at first. It’s simple enough to find the play button and drop-down to select your build target. But what if you want to do an adhoc distribution build? Fortunately, there are plenty of resources out there for learning Xcode.
How about Android builds? This is an area that I am not as familiar with. Because the React Native CLI is capable of building to a device, I haven’t tried to build the project with Android Studio. I have generated a signed APK. The React Native documentation has a guide, but it comes down to using gradle.
Editing the App
React Native does not provide an IDE like Axway Appcelerator Studio. The documentation does suggest taking a look at Nuclide. Nuclide is a package for Atom that claims to setup an environment for developing React Native. I found I wasn’t taking advantage of its features, so I uninstalled it after a couple days in favor of just Atom.
So you can open the code in a text editor, where do you go from there? With a Titanium project, at least an alloy one, the entry point is alloy.js. From there the index controller has loaded first automatically. React Native provides entry points at index.android.js and index.ios.js. From there you can load whatever components you wish. The simplest thing to do is to edit some of the text provided with the sample project. Once you’ve made an update you can easily see your changes without rebuilding your app!
Axway Titanium provides a live view feature to see your app update as code changes. React Native offers a similar feature. On simulator you can press command + R to reload the code from the React Native packager. On an android emulator you can achieve the same thing by tapping R twice. Reloading can also be accessed from a built-in developer menu! To access the developer menu simply shake your device. You will see options to reload, enable remote JS debugging, enable live reload, and more.
Debugging Your Code
Axway Titanium attaches a console to builds made directly to a device, emulator, or simulator. The React Native process ends as soon as a build is installed and does not attach a console. Instead, you can enable remote debugging through the developer menu and debug your app in Google Chrome. You do not see a DOM representation of the app, but you do get access do the console and debugging tools! The debugging is done over TCP, so you don’t need to have built on a device connected to your computer. Inside the developer menu, you can change the URL used for remote debugging so you can debug as long as the device and machine running Google Chrome are on the same network.
This has only been a brief look at getting started with React Native. In the future, I would like to revisit this topic to discuss more configuration, component driven design, and interacting with native code. React Native is very young, but it has come a long way in a short period of time. I am very excited to see how it matures as a cross-platform framework.
Debugging is one of the most frustrating aspects of software development of any kind – it is also one of the most essential. Finding a malfunction can be time consuming; therefore, it is important to have effective tools that can decrease your debugging time. For Titanium, most of my debugging consisted of log statements and alerts. While this method can be useful, it can also be a little time consuming to rebuild and to log a different variable, collection or model.
One of my coworkers saw me using this log for debugging and suggested an alternative: using Safari Web Inspector. I was very surprised at how easy it was to set up and how effective it can be throughout the process. This one line is all you need to add to your “tiapp.xml” file in your project:
under the <iOS> flag. Unfortunately, this method only works on an iOS simulator. Once you have updated your tiapp.xml, build your project and navigate to the page you would like to inspect. Next you will need to open Safari; if the develop tab isn’t visible you will need to follow a couple extra steps:
Select the Safari tab from that dropdown navigate to preferences then check “Show develop menu in bar.” After the Develop tab is visible you will open the Simulator option and then select JSContext.
This is where all the magic happens. The files where breakpoints can be inserted will be visible on the left panel of the screen. Breakpoints are very convenient for stepping through your code and seeing exactly what is happening. I suggest opening the right panel when the breakpoints are hit. This is where you will find local variables and can also add Watch Expressions. Watch Expressions is the place where you can add the variables that you would like to keep an eye on. You will be able to see and follow each variable through every step of your code.
The bottom console is also a very helpful aspect of this debugger. I use this for taking a look at any model or collection to inspect in detail what they contain. This has been a lifesaver for me. It makes it easy to investigate exactly what is going on with any unexpected behavior with your models or collections.
The safari web inspector has it’s problems and will, from time to time, crash the app – but overall this tool has helped me immensely debugging my titanium apps. It makes it so effortless to nail down exactly where the problem lies. As much as we all want to have flawless code without bugs, they will appear every once in awhile. However, this tool can save you from the frustration those bugs can cause. As I stated before, it is very easy to set up, so jump in and play around with it a bit. Have any questions or comments? Feel free to share your your tricks for debugging. Also, you can find our latest apps and check out our work here.
Editor: In case you need to know other ways we used to debug Titanium Apps, please also check Appcelerator Titanium iOS Debugging with XCode or Rapid Titanium WebView debugging with Chrome Developer Tools
A Grid View is pretty common in many applications nowadays, displaying images or a variety of image and text content to the user in a repeated pattern cells in a vertical and horizontal layout. This component is highly favored over List Views and Table Views when wanting to compare similar data types as well having a better visual comprehension that helps to distinguish the subsets of items.
However, when it comes to Titanium, they don’t have any reference to a Grid View. So what does that mean for our image heavy applications that would like to display a list of images? You could use a list view if you are able to supply enough information that would allow the user to easily read and comprehend the list. But, if you have limited data or none at all it would be more visually appealing to display a Grid View. Which brings us back to the problem at hand, Titanium does not have any reference to a Grid View.
Let us explore our options:
If you know that your data won’t change you could just do some calculations to disperse your views across the screen in the xml. This would be good for navigation where each button would have separate functionality when clicked.
However this may get a bit messy and annoying when you have to calculate for up to 20 or more views. Which brings us to
Let’s create a Grid View that has three columns and four rows.
This option gives us a very faux Grid View by using the Table View as a crutch by populating each row with several cells. This is a good option and simply by doing some math to determine the amount of rows you’d need for your data set you can make this very flexible to allow for an undetermined data length. However, a problem with this approach is that a user may notice that the entire row shows feedback for being selected. This can be avoided by substituting the Table view for a Scroll View and instead of using Table Rows, just use a View that spans the entire width and add the cell View accordingly.
Simply use a module. There are several good modules out there that not only make it very easy to add a grid to your project but they also add a lot of extra cool features to the Grid View like TiCollectionView and TiFlexiGrid
There are plenty of other ways to create a Grid View that aren’t mentioned above. Titanium allows for a immense of other possibilities to creating a Grid View and the only thing that you need is imagination and some problem solving skills. So even though Titanium lacks a simple way to incorporate a Grid View within your app, that does not mean you can’t Jimmy Rig your own.
I recently took the time to checkout out Appcelerator’s Labs page where they allow users try out pre-release software. There are some interesting projects here, but I spent most of my time experimenting with Hyperloop, which could be the best new feature in Titanium.
I think Hyperloop will be one of the best additions to Appcelerator’s arsenal, but there are some improvements I would like to see before its final release.
In a typical project using Hyperloop, I might write something like this if I needed to require some native Android API’s:
A more complicated example that uses a lot of native API’s could look like this:
This looks a little messy. I would like to see ES6 style destructuring and object matching. That could make the code above look something like this:
This could make the code much more readable as classes from the same package will be grouped together, and var’s with matching names will be created automatically.
I, personally, cannot wait to start using Hyperloop in my daily development here at Shockoe. I think it will not only let me make more powerful applications that harness more native API’s, but it will also save me time when using third party libraries. Fewer native modules means less code to maintain down the line when operating systems and SDK’s are updated.
I think Appcelerator has a great product in development, and with a few improvements, it will be invaluable to the Appcelerator developer community.
Event listeners. Callback functions. Asynchronous programming? These words were foreign to me when I first started working at Shockoe LLC the first week of October 2015. But somehow, I needed to use these things to create a mobile application in the next two months.
Showing up to work on the first day taught me that that wasn’t the case. Edwin, the CEO at Shockoe, assigned me to work on Fighting Mongooses, a name with which I’m now beginning to understand the logic behind.
The concept behind the app sounded pretty simple but integrating various devices, a server, a database, and mobile OS’s turned out to be far more complex than I had anticipated.
The first week or two was spent just trying to figure out what was actually happening in this partially built application. I slowly started to figure out what the different pieces of code were doing to understand the logic. I used what was already available to piece together a rudimentary working application to fulfill the initial requirements and to prove I could fit in at Shockoe.
There is still a lot that I need to learn to get near the level of the other developers here, but I have had some great guidance and help while working on the Fighting Mongooses project.
I still have much that I wish to accomplish with the application and feel more comfortable and confident each day with what I’m doing.
I recently found an old version of the app on a device I used for testing about a month ago and it’s amazing to see for myself the progress that I have made since.
I look forward to see the kind of progress I can make in the next month on onward here at Shockoe.
Earlier this week, I was debugging and I was reminded of the sheer power of the XCode developer tools, even in the context of a not-quite-native application like a titanium application.
Andrew was working on an application that will load in a large number of images and PDFs from a remote server and display them to the user, in-app. However, when we got to the point that we would be displaying a certain one of our images, we saw this in the Titanium console:
Sorry, what? It seems like something odd is happening at a native level, and Titanium is getting too confused to return a sensible error message. Well, guess it’s time to open a support ticket with Appcelerator and wait for them to figure out what the issue could be, right?
Wrong. One of my favorite things about Appcelerator Titanium is its open-source nature. What we can do from here, is open up the native project generated by Titanium and debug it with the normal native debugging tools. When you build a Titanium application for iOS, a (pretty much) normal XCode project is generated from your project, compiled, and run on whatever test device you have selected. In situations like this, we can take that project and manually re-build it in XCode for debugging purposes.
Opening your project in XCode
To open your project in XCode, first run
in your project’s directory. This will ensure you have a native project generated for your Titanium project. From here, all you need to do is open XCode, and open up the XCode project in the build/iphone folder.
Setting Native Breakpoints
Now that we’ve got the project in XCode, we need to set up a native breakpoint so that we can see what the issue is with the Objective-C code that Titanium is executing on our behalf. Fortunately, the message that Titanium printed out gave us a selector name:
. Let’s go ahead and set up a symbolic breakpoint for that selector:
Enter the XCode debugger
Now that we’ve got our breakpoints set up, we can run the project in XCode, and execution will stop when our breakpoint is hit in the Titanium SDK code.
Let’s go ahead and step over a few commands and see if we can figure out exactly what’s going wrong.
Huh, it looks like we’re having some issue turning our Titanium file into a UIImage that we can apply to the native UIImageView. Let’s use the variable inspector to figure out exactly why we’re failing to convert this into an iOS image.
Well, one look at the MIME type is enough to see exactly what’s wrong. Our file isn’t an image! Even though this didn’t tell us exactly where the issue was, it was enough to direct our debugging (we eventually figured out that we were accidentally saving a PDF file as an image – oops!). Issues like this are why I’m very quick to reach for XCode when I see a native iOS issue – it makes it much easier to figure out what parts of your code might be incorrect when you can easily trace through Appcelerator’s code!
Dependencies and upgrading
If your project is built with Alloy, good news! An older version of Backbone ships with Alloy by default, as well as its underscore dependency. If you’re maintaining a classic Titanium project, you can download the most recent version of Backbone and underscore from here and use them like normal commonjs libraries. Additionally, we have provided an updated version of Backbone that has been modified to work with the current version of Alloy. To use it in an Alloy project, just place the minified version in your lib folder and add
An aside on the topic of mixins
On to the main Backbone.Event
The core advantage of building a Titanium app with Backbone is its powerful event system, and it couldn’t be easier to use. To mix in Backbone Events to an alloy controller, just add
Now that you have backbone events mixed in to your controller, you can start listing to and triggering them. First, let’s set up an event listener.
To break down that code snippet, using the ‘on’ function from underscore you can subscribe a function to be executed every time that some event is fired. Then, from whithin the other controller, you can use the ‘trigger’ function to notify listeners of some action. For example, if you had some picker controller, you could trigger a ‘change’ event whenever the user makes a new selection, and then listen for that event from the parent controller.
So why not normal callbacks?
Secondly, Backbone exposes a handful of functions that makes it very easy to clean up event listeners en masse. You can use ‘off’ to dismiss event listeners individually, dismiss listeners for an individual event, or tear down every event listener associated with a given object.
In addition to this system for managing events, the most recent version of Backbone provides a number of functions to allow objects to better manage their event listeners.
The advantage of using the listenTo pattern is that either object can tear down an event listener shared by them. This has important implications for Alloy controllers: as long as you manage most of your cross-controller interactions through Backbone.Events, you can tear down every event listener originating from a controller with a single call. We can use this feature to set up intelligent disposal functions that let us tear down most references to a controller quickly and prevent memory issues.
And that’s it. From here, you can set up other controllers to listen to the dispose event and do things like remove the controller when its disposed or build out new UI on controller disposal. Then, after all of the dispose listeners have been handled, all event relationships are automatically disposed of. Assuming you clean up all of your references in dispose events, there’s nothing else you need to do for the average controller to keep memory in check. Bear in mind that things like app-wide events (such as events on Titanium.App, Titanium.Geolocation, Titanium.Gesture, etc.) can still lead to memory leaks and should be handled in your disposal listeners.
You can read more about Backbone.js at the project’s website.
For more information about Backbone’s dependency Underscore and how you can use it to code better and faster, check out our blog post!
This document is intended for the average Titanium Developer to enable push notifications. It is assumed that the reader already has a basic knowledge of Titanium and the APIs.
Today we will talk about Part 2 of 3 of Push Notifications, which begins with Google App Registration.
Register your application with Google
Create a Google API Project
Register with Appcelerator Cloud Services
Step 1 : Create a Google API Project
You will need to open the Google Developers Console by visiting https://cloud.google.com/console. From there you will need to sign in with your Google ID that you want associated with this project. Once signed in you will see a basic screen and a big red button that says ‘CREATE PROJECT’.
Enter a Project Name, and ignore Project ID. Project ID is randomly generated by Google to avoid duplication of IDs. Click the ‘Create’ button and the Google Developer.
Console should refresh. Now you should be on the projects Overview page. At the top of this page you will see Project ID and Project Number.
Copy the Project Number, since this will be used at a later point as the GCM Sender ID. On the left corner of the page there is an APIs & Auth section. Go to that page and a list of API items will populate. Turn On the Google Cloud Messaging for Android.
Again under APIs & Auth you will see ‘Credentials’, click there. Now you will see a section called ‘Public API Access’. Click the ‘CREATE NEW KEY’ button to generate an API Access Key.
A popup will appear, on that select ‘Server Key’. Another popup will appear asking you to enter IP Addresses in the text field, just click ‘Create’.
DO NOT ENTER ANY IP ADDRESSES
Now under the Public API access section there is a section for API key with a rather strange combination of letters & numbers. Copy that text and hang onto it. Now go to the Appcelerator Dashboard https://dashboard.appcelerator.com/.
As before select the app you are working with and click the ‘Cloud’ tab. On the left menu click ‘Settings & Configurations’. Then on the tabbed menu click ‘Android Push’. It will ask you for the GCM API Key and GCM Sender ID, which you should have saved. Enter those values in and click ‘Save Changes’.
Implement the code into a Common JS library
Ensure that you are using a Common JS library for notifications. Create a ‘notifications.js’ file inside the ‘lib’ folder. If the folder does not exists then create it.
iOS Code Setup
With iOS you must use Ti.Network.registerForPushNotifications the first time the user enters the application. After registering with the server, the function should return a device token. Save this device token in app properties.
Example : Ti.App.Properties.setString(‘deviceToken’, e.deviceToken);
However make sure you set the application properties on the callback and not inside the common JS library. These lib files can sometimes act strangely when it comes to saving app properties.
The device token that is generated will allow the application to receive notifications. You will be able to register the device with ‘Channels’. The server can push information to certain Channels. Say you want sports news updates. Then a Channel called ‘sports_updates’ could be created. Channels are not done on the server side. Creation is done on the user side. There is not a way to manually add a channel on the ACS Dashboard. Once a user subscribes to a channel for the first time then it is created.
Subscribing a device token to a channel is a function in the common JS library you created for Push Notifications. In this function we pass two variables. One being the channel and the other being the device token that was generated earlier. Each one is needed for the subscription.
You will also need to allow the user to unsubscribe from Channel based Pushed Notifications, which can be done using the unsubscribe function.
Now we need to create a sample page to test this all out with. It will have a view, label, and button. Clicking this button will subscribe the user to sports updates from the ACS server.
This will create a basic view with a label and button on top of the window. It will say ‘Sports’ and upon click will call the register function from the notifications lib file.
You can also have users set up on the ACS server and log them in and subscribe to channels. However the user account must exist. Generally one user is created for the public, such as the ‘push_notifications’ user we see in the code. This is perfect for just a basic app with notifications. If you want user sessions and give the ability for people to create their own accounts you will have to look into Titanium.Cloud.Users on the documentation.
Try it and leave a comment below to let us know if you had any problems following these steps.
We will continue next week with part 3.
Titanium mobile allows you to develop without worrying about native code, but that doesn’t mean that you should ignore native user expectations! The Android back button is a core piece of native android look and feel, and while users probably won’t notice when back behavior is done well, they’ll definitely notice when it’s done poorly. In this article, we’ll go through some tips and tricks that the Shockoe team and I have found useful for providing quick, intuitive, and maintainable android back behavior, and construct a simple application implementing these behaviors.
Treat your views like a stack
Or rather, maintain a stack of back behaviors that manage your view hierarchy. Users expect for the android back button to ‘undo’ their last major change in the app’s state, and using a callback stack is a very easy way to keep track of all of your user’s actions, in order. With this in mind, we can set up our app to handle back button presses gracefully from the first window.
This sets up your app to maintain a list of back behaviors, and once they have been exhausted close the app. Now let’s try adding another view.
And that’s it! Our simple little demo app is now set up to gracefully and consistently handle android back behaviors for a simple view hierarchy. Handling more complex view hierarchies will obviously require more complex android back handlers, we’ll go over handling the android back button in more complex apps in the next entry in this series.