Why We’re Rebranding: a Letter from Our CEO

Why We’re Rebranding: a Letter from Our CEO

Hello from the world of Shockoe!

As some of you might have noticed over the last few days, Shockoe is sporting a brand new logo. It’s an exciting era for our company — our steady growth has brought new clients, new teammates, and pushed us into our larger digs in Scott’s Addition. It’s a great time for Shockoe!

You’ll see it’s not just our logo that is changing. We’ve changed our website, our social media, our messaging, and our focus to better reflect the way we help our clients succeed. What we’re saying should not sound unfamiliar to those who have worked with us. Our mission is only a refined version of what we have always known well about ourselves: we make quality apps that make users lives measurably better. In short, we’re Shockoe: we’re mobile by design.

So what’s changed?
Actually, not much. We’re bigger and better — our consulting-focused approach to developing apps remains, but is now a thriving team of developers, strategist, and designers. We have 35+ talented individuals and a growing client portfolio that we can be proud of. It’s truly our growth that has helped us realize our focus and expand the breadth of expertise that Shockoe truly represents.

From grocery store apps in the southeast to managing herd health in Canada — it’s felt like we do a bit of almost everything. That said, we have seen a few trends surface, and began to recognize we are particularly fantastic in a few different areas of mobile development. It’s what we’re calling our “pillars,” and what is ultimately the driving force behind the utility apps we create. What are these pillars? I’m glad you asked!

If you want to learn more about what each one means, I encourage you to visit our new website where you can read more on each pillar and read supporting case studies. Additionally, our latest three blog posts take a leap into the various pillars as we aim to push thought leadership that helps companies bring mobile apps to more processes, internal operations, and customer loyalty strategies. I encourage you to hop in and check things out.

We’re incredibly proud of the work that we do at Shockoe and thankful for the employees, the partnerships, and clients that have accompanied us in our growth. We owe this rebrand to all of you.

As always, if you have any questions, please don’t hesitate to reach out! Until then, keep an eye on Shockoe as we continue our growth and continue our campaign to be the best damn mobile shop around.

Sincerely,

edwin huertas signature

 

Edwin Huertas, CEO

Can you QA test this? …

Can you QA test this? …

… is the first question an agile developer should ask of them self.

Agile development is a continuous, flexible feedback loop driven by collaboration, adaptive planning, dynamic development, early delivery, and constant improvement. This continuous integration approach to development has a dark side – the potential to continuously integrate defects.

Successful agile development requires testing as a strategic component of each project: Agile development requires agile testing.  As code architects and engineers, developers are best qualified to identify areas of potential risks. Developers are critical in creating and implementing an efficient, effective testing strategy.

Developers are the first line of defense in detecting and eradicating defects. Applying best practices during coding reduces the number of introduced errors. Catching and correcting defects before they are introduced into a distributed app is far more productive than pinpointing and fixing a multitude of problems days or hours before delivery deadlines.

Testing on developer environment simulators is the first means of testing an app, however, it does not expose all defects. Simulators do not represent the actual device or user events encountered in real device use. Actual devices are the only means to test real user experience – have you ever seen an end-user run their app on a simulator?

After passing initial testing on the development simulator, the app is ready to be built on the continuous integration (CI) environment. Builds deployed to devices from the developer environment may not exhibit defects resulting from different CI configurations. While CI performs testing on various levels, developers should verify and validate CI builds prior to passing apps to third persons for manual testing or automated QA frameworks outside the CI.

Developers using cross-platform solutions, such as those used by Shockoe, can often decrease development time, testing complexity, and costs. Today’s multitude of device chipsets, memory, display, sensors, OS versions, OEM and carrier modifications, and third party software dependencies can make “test often” overwhelming, expensive, and dramatically reduces the time a developer can spend developing.  Shockoe employs tools to streamline the seemingly endless possibilities of testing required to assure stable products and heightened user experience.

Automated testing on actual devices can be performed in-house and by cloud-based services. These automated testing frameworks increase the number of tests that can be run in a time frame, reduce the time it takes to expose defects, and shortens overall time to market. Automated testing frameworks do not make errors. Developers should witness the first few automated passes, as they are most familiar with the product’s performance expectations and nuances.

Human testing comes with long time cycles, high costs, and is prone to errors. While automated testing solves these human detriments, they do not accurately test for design issues and overall user interaction experience. Whether testing in development simulators, performing manual tests on CI builds, or watching the first few passes of an automated test, only a human can test for human experience factors.

Developers produce the code that is the app. They are integral to the testing processes at all levels of production. Before a developer asks, “Can someone QA test this?” they should employ development best practices, testing techniques, and tools to ensure those “QA-ing” find few, if any defects.

Appcelerator Titanium iOS Debugging with XCode

Appcelerator Titanium iOS Debugging with XCode

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.

The Problem

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:

[ERROR] invalid image type. expected TiBlob, String, TiFile, was: TiBlob -[TiUIImageView setImage_:](TiUIImageView.m:687)

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

ti build -p ios --build-only

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.

Path to a Titanium project's compiled XCode Project

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:

-[TiUIImageView setImage_:]

. Let’s go ahead and set up a symbolic breakpoint for that selector:

Add a breakpoint in XCode by clicking the second icon from the right in the side bar, and then clicking the plus in the bottom right

Add the symbol from the error as the symbol name

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.

The debugger will automatically pause execution when you hit a breakpoint.

Let’s go ahead and step over a few commands and see if we can figure out exactly what’s going wrong.

Step Over

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.

XCode variable inspection

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!

API Description Language for the Enterprise

API Description Language for the Enterprise

REST, now estimated to be used by 90% of new APIs, is great for groups within a corporation that can engineer their API as quick as lean startups. However, REST doesn’t fully meet the needs for enterprise businesses. With their slow-moving review and approval processes, internal politics, and sometimes a large user base, enterprise businesses require an API that can be simple to manage, quick design process and also be able to use standardization across potentially hundreds of other APIs across multiple line of business.

It’s been more than a couple years now since we started to look for API Description Languages that can fit small to large companies. Anything that can help the communication between Back-End and Front-End developers to be fast, easy and standardized, it’s been something that we always strive for. Swagger and RAML, both are API Description Languages that meets those needs.

It has been suggested that RAML may be the perfect solution for designing the next generation of enterprise level APIs, but as you might know enterprises still using SOAP based APIs and, of course, WSDLs are still the king.

With Swagger or RAML, at the end of the day, you are trying to describe an API by writing JSON, and since it’s JSON, there are many tools out there that will help you generate these documents via nice editors (GUIs).

 

Rapid Titanium WebView debugging with Chrome Developer Tools

Rapid Titanium WebView debugging with Chrome Developer Tools

Any Web Developer worth their salt is already familiar with the awesome Chrome Developer Tools package that ships with Google’s Chrome Browser.  What you might not know is that Android 4.4 introduced a powerful new native debugging tool for native Android/HTML5 hybrid apps that allows you to attach Chrome Developer Tools to a Web View running on a physical android device.  As part of our continuing mission to help you tame the Mobile Monster, we’ve taken the liberty of wrapping the code to enable this functionality in a Titanium-ready mobile module.  To make use of this new functionality in Titanium, you will need :

  • A laptop with the Google Chrome Browser
  • A phone running Android 4.4+ (and a charging cable)
  • An app built with Titanium SDK 3.4.1.GA +

Getting Started

First, download the pre-built module below.

[ No module needed on Android 4.4.x+ ] (update)

To make use of the module within your Titanium project, you just need to un-zip the module into your modules folder, and add it to your modules tag in your tiapp.xml.  We recommend only including this module for the development deploy type, since this is purely a debug tool.



com.shockoe.debug.webview

Now, just build your app to an Android 4.4+ device, and you will be able to attach chrome developer tools to any web view within your app.

Attaching Chrome Developer Tools

Once you have your app on your test device, and have your test device connected to your development laptop, open Google Chrome and type chrome://inspect into the address bar.  This should open you up in the devices tab.

 

The Chrome developer tools device perspective

Then just click inspect.  A normal Chrome developer tools window will open, allowing you to inspect your element as normal.  In addition, you can click the new icon in the top-right of the screen to get a live preview of your WebView directly within the inspector window.

The Chrome Developer Tools inspector with on-device preview

 

And that’s it. You now have a full-featured Chrome Developer Tools window attached to your Titanium app’s WebViews, allowing you to use all of the same web development tools that you are familiar with from normal HTML/CSS/JavaScript apps to develop Titanium/Mobile Web hybrid apps.

Enabling Push Notifications Part 3 of 3

Enabling Push Notifications Part 3 of 3

Android Code Setup

Android is set up the same way with just a few minor differences.  On Android, we use the ti.cloudpush module and ti.cloud for Push Notifications.  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.

//require the notifications common js lib file
var notifications = require('notifications');
//check for a device token
var deviceToken = Ti.App.Properties.getString('deviceToken');

//check to see if deviceToken exists
if(deviceToken === '') {
	//get the devices token
	deviceToken = notifications.getToken();
	//set the deviceToken app property
	Ti.App.Properties.setString('deviceToken', deviceToken);
}

In the index js file we set up the device to look for a token and if there is not one to register the user for Push Notifications.

//require ti.cloudpush module
var CloudPush = require('ti.cloudpush');
//require ti.cloud module
var Cloud = require('ti.cloud');

//get device token
exports.getToken = function() {
  // Initialize the module
  CloudPush.retrieveDeviceToken({
      success: deviceTokenSuccess,
      error: deviceTokenError
  });
  // Enable push notifications for this device
  function deviceTokenSuccess(e) {
      CloudPush.enabled = true;
      return e.deviceToken;
  }
  function deviceTokenError(e) {
      alert('Failed to register for push notifications! ' + e.error);
  }
  // Process incoming push notifications
  CloudPush.addEventListener('callback', function (evt) {
      alert(evt.payload);
  });
};

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.  Then a Channel called ‘sports_updates’ could be created.  Channels are not done 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.  Now the module ti.cloud will be required for this project as well.  The first module, ti.cloudpush, is just for registering a device token, and ti.cloud does the rest.  So we add ti.cloud to the notifications lib file.

//subscribe to a specific channel
exports.subscribe = function(channel, token) {
    Cloud.PushNotifications.subscribeToken({
        device_token: token,
        channel: channel
    }, function (e) {
        if (e.success) {
            alert('Subscribed');
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

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 is 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.

//unsubsribe from a specific channel
exports.unsubscribe = function(channel, token) {
    Cloud.PushNotifications.unsubscribeToken({
        device_token: token,
        channel: channel,
    }, function (e) {
        if (e.success) {
            alert('Unsubscribed');
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

//device token
var deviceToken = Ti.App.Properties.getString('deviceToken');
//require notificiations lib file
var notifications = require('notifications');
//create view to house label and buttons
var container = Ti.UI.createView({
	width           : Ti.UI.FILL,
	height          : Ti.UI.FILL,
	top             : 30,
	layout          : 'vertical',
	backgroundColor : '#FFFFFF'
});
//create label for title
var channelLabel = Ti.UI.createLabel({
	width     : Ti.UI.FILL,
	height    : Ti.UI.SIZE,
	text      : 'Select a Channel',
	textAlign : 'center'
});
//create sports channel button
var sportsButton = Ti.UI.createButton({
	width     : Ti.UI.FILL,
	height    : Ti.UI.SIZE,
	top       : 10,
	title     : 'Sports'
});
//sports button event listener
sportsButton.addEventListener('click', function(e){
	if(deviceToken !== '') {
		notifications.subscribe('sports_updates', deviceToken);
	} else {
		alert('Error, device not registered for Push Notifications');
	}
});
//add elements together
container.add(channelLabel);
container.add(sportsButton);
$.win.add(container);

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.

notifications.js

exports.userLogin = function() {
    // Log in to ACS
    Cloud.Users.login({
        login: 'push_notifications',
        password: 'pushy'
    }, function (e) {
        if (e.success) {
            alert('Login successful');
        } else {
            alert('Error:\n' +
                ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

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.

Sending Push Notifications using the Dashboard (http://dashboard.appcelerator.com)

This will cover three different ways for notifications to be sent.

Sending to Specific Channel/Users
Sending to All Channels
Setting up Recurring Notifications

 

Go to the Dashboard, then Cloud, then Push Notifications.  You will see a button that says ‘Send Push Notification’, click on it.

Sending to Specific Channel/Users

  • Channel – Which channel to send the notification to

    • Choose ‘Specific Channel’

  • Choose ‘Specific Channel’

  • Users – You can choose to enter a username if you have created any to notify just users who subscribe to that channel.

  • Alert – The message body you want the user to see

  • Send When – The time you would like to send the notification

    • Choose ‘Send Now’

  • Title – The title of the notification

Let’s say we notify the ‘sports’ channel, then we need to choose ‘Specific Channel’ under the Channel.  Then under ‘Channel Name’ you would put ‘sports’.  The ACS server is Case Sensitive, so stick with lowercase or camel case.  For the ‘Alert’ section just come up with something such as ‘Richmond, Virginia to get a Major NFL Team’.  Under ‘Send When’ choose ‘Send Now’.  Then for ‘Title’ enter ‘WZYB Sports’ or something like that.

 

Click ‘Save Changes’ which will send the notification to the subscriber devices.

Sending to All Channels

  • Channel – Which channel to send the notification to

    • Choose ‘All Channels’

  • Alert – The message body you want the user to see

  • Send When – The time you would like to send the notification

    • Choose ‘Send Now’

  • Title – The title of the notification

Click ‘Save Changes’ which will send the notification to the subscriber devices.

Setting up Recurring Notifications

  • Channel – Which channel to send the notification to

    • Choose ‘All Channels’ or ‘Specific Channel’

  • Alert – The message body you want the user to see

  • Send When – The time you would like to send the notification

    • Choose ‘Recurring’

    • Enter the Start Date, End Date, Cycle and Time of Day

  • Title – The title of the notification

Click ‘Save Changes’ which will send the notification to the subscriber devices.

That concludes this tutorial on Push Notifications.  Please feel free to leave a comment and let us know if this worked for you.

 

Enabling Push Notifications Part 2 of 3

Enabling Push Notifications Part 2 of 3

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

Android Setup

  1. Create a Google API Project

  2. 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 to be 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.

The 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 here.  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.

index.js

//require the notifications common js lib file
var notifications = require('notifications');
//check for a device token
var deviceToken = Ti.App.Properties.getString('deviceToken');

//check to see if deviceToken exists
if(deviceToken === '') {
	//create a device token by registering for notifications
	deviceToken = notifications.register();
	//set the deviceToken app property
	Ti.App.Properties.setString('deviceToken', deviceToken);
}
//open the index window
$.index.open();

//controller
var mainWindow = Alloy.createController('Main').getView();
//open the mainWindow
mainWindow.open();

notifications.js

//require ti.cloud for iOS Notifications
var Cloud = require('ti.cloud');

//register the device and receive a token
exports.register = function() {
    Ti.Network.registerForPushNotifications({
        // Specifies which notifications to receive
        types: [
            Ti.Network.NOTIFICATION_TYPE_BADGE,
            Ti.Network.NOTIFICATION_TYPE_ALERT,
            Ti.Network.NOTIFICATION_TYPE_SOUND
        ],
        success: deviceTokenSuccess,
        error: deviceTokenError,
        callback: receivePush
    });
    // Process incoming push notifications
    function receivePush(e) {
        alert('Received push: ' + JSON.stringify(e));
    }
    // Save the device token for subsequent API calls
    function deviceTokenSuccess(e) {
        return e.deviceToken;
    }
    // Display an error upon failure to register
    function deviceTokenError(e) {
        alert('Failed to register for push notifications! ' + e.error);
    }
};

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.


//subscribe to a specific channel
exports.subscribe = function(channel, token) {
    Cloud.PushNotifications.subscribeToken({
        device_token: token,
        channel: channel
    }, function (e) {
        if (e.success) {
            alert('Subscribed');
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

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 is the channel and the other being the device token that was generated earlier.  Each one is needed for the subscription.


//unsubsribe from a specific channel
exports.unsubscribe = function(channel, token) {
    Cloud.PushNotifications.unsubscribeToken({
        device_token: token,
        channel: channel,
    }, function (e) {
        if (e.success) {
            alert('Unsubscribed');
        } else {
            alert('Error:\n' + ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

You will also need to allow the user to unsubscribe from Channel based Pushed Notifications, which can be done using the unsubscribe function.

Main.js

//device token
var deviceToken = Ti.App.Properties.getString('deviceToken');
//require notificiations lib file
var notifications = require('notifications');
//create view to house label and buttons
var container = Ti.UI.createView({
	width           : Ti.UI.FILL,
	height          : Ti.UI.FILL,
	top             : 30,
	layout          : 'vertical',
	backgroundColor : '#FFFFFF'
});
//create label for title
var channelLabel = Ti.UI.createLabel({
	width     : Ti.UI.FILL,
	height    : Ti.UI.SIZE,
	text      : 'Select a Channel',
	textAlign : 'center'
});
//create sports channel button
var sportsButton = Ti.UI.createButton({
	width     : Ti.UI.FILL,
	height    : Ti.UI.SIZE,
	top       : 10,
	title     : 'Sports'
});
//sports button event listener
sportsButton.addEventListener('click', function(e){
	if(deviceToken !== '') {
		notifications.subscribe('sports_updates', deviceToken);
	} else {
		alert('Error, device not registered for Push Notifications');
	}
});
//add elements together
container.add(channelLabel);
container.add(sportsButton);
$.win.add(container);

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.

notifications.js Again


exports.userLogin = function() {
    // Log in to ACS
    Cloud.Users.login({
        login: 'push_notifications',
        password: 'pushy'
    }, function (e) {
        if (e.success) {
            alert('Login successful');
        } else {
            alert('Error:\n' +
                ((e.error && e.message) || JSON.stringify(e)));
        }
    });
};

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.

Increasing Your Coding Efficiency with Sublime Text

Increasing Your Coding Efficiency with Sublime Text

It’s no secret that Sublime Text has an extensive, robust set of features of which not all users might be aware. I’m here to share with you some of the ones that I find myself most often using to reduce the tediousness of repetitive tasks, and increase overall efficiency while developing in Alloy/Titanium. I will be posting hotkeys for all platforms at the top of each section, but for readability’s sake and it being the platform I primarily develop on (and because I went through the trouble of finding the ⌘ symbol to copy/paste), I will be focusing mainly on the Mac hotkeys for the majority of the blog.

Multi-line Selection

  • Windows: Ctrl-Left Click, Ctrl-Alt-Up/Down
  • Mac: ⌘-Left Click, Ctrl-Shift-Up/Down

This feature is the bread-and-butter of Sublime Text in its ⌘-Click incarnation, but did you know that Ctrl-Shift in combination with the Up and Down arrows on your keyboard achieves a similar effect without having to waste precious seconds reaching for that peripheral? For the uninitiated, this feature allows you to create multiple cursors in your file, making features such as creating numerous, similar elements, or editing large blocks of similar code incredibly expedient. Ctrl-Shift-Up/Down expands your cursor above and below its current location, giving you control of multiple lines. If you accidentally go a line too far, ⌘-U will incrementally revert your line expansions.

example

ctrl-shift 1

These rows we created all need to be styled identically.
How about we add a class?

ctrl-shift 2

Ctrl-Shift-Down a few times…

ctrl-shift 3

…and bam! Class added, no additional typing or copy/pasting necessary

The applications for this feature are too numerous to go into in such a short blog, but I encourage you to play around with it. Once you’ve gotten the hang of it, formatting, styling, adding, and removing code will look and feel like a relaxing ballet of dancing characters and symbols, rather than a chore.

Column or “Block” Highlighting

  • The commands for this are numerous, so check out their docs here.

Going hand in hand with multi-line selection, highlighting blocks of code is a more esoteric, yet nonetheless potent feature of the text editor. Alt-Click and Dragging on Mac will ignore all formatting in place and highlight whatever you have selected into a neat, concise block. I don’t use this as much, but it is particularly nice in TSS files where I have properties like borderRadius, borderWidth, and borderColor all sitting in a nice row just waiting to get styled.

Repeat Highlighting

  • Windows: Ctrl-D
  • Mac: ⌘-D

With nothing highlighted, pressing ⌘-D grabs whatever is directly in front of your cursor and highlights it up to the next logical stopping point. Your cursor is in front of some whitespace? This will highlight up to the next text. In front of text? It highlights up to the next separator. You can also, of course, manually highlight what your desired selected area, but this is when that Sublime Text greatness kicks in: subsequent presses of ⌘-D will additively highlight the next instance of your current selection. The synergy between this feature and multi-line editing cannot be understated.

XML files are a great example of where this shines. Multi-line and block selection are not of much use if all of the elements/id’s/classes you need to edit are on different columns. With ⌘-D, you can select each of them one-by-one. But wait, there’s more! Should you decide that not every single instance of your selected code needs highlighting, ⌘-K,D skips over your current selection and highlights the next instance instead. It’s awesome.

example

cmd-d 1

After highlighting the first dataRow, Sublime Text already starts pointing out subsequent instances.

It’s chomping at the bit to make your life easier!

cmd-d 2

A few more key presses and we have a nice set of highlights

cmd-d 3

Whoops! Didn’t need that third one, so we skip it with ⌘-K,D

 Block Indentation

  • Windows: Ctrl-] , Ctrl-[
  • Mac: ⌘-] , ⌘-[

While one my most frequent uses of Ctrl-Shift-Up/Down is to indent blocks of code, you may have noticed that it will only expand your cursor to a column on the line that already exists; that is, it won’t create whitespace that does not already exist, and as such will snap to the left if you have lines that you skipped for readability. This can be annoying if you’re trying to indent with multiple lines selected, but fear not! After highlighting any block of code, a simple click of ⌘-[ or ⌘-] will indent that block one tab left or right, respectively. Easily one of my favorite shortcuts, this feature makes formatting code incredibly quick and easy.

And finally, Highlight Scope

  • Windows: Ctrl-Shift-Space
  • Mac: ⌘-Shift-Space

This feature is highly underrated, in my opinion. It’s a useful debugging tool, especially when you’re working with a large function in your controller that may have a misplaced bracket somewhere. It does what its name implies: key in the command and you will highlight the next step up in scope, starting at your cursor’s location.

example

scope 1

scope 2

scope 3

 

 Sublime Text also has a package manager, through which you can download numerous plugins to improve its functionality, and tailor its usage to your needs. I currently have it linting my JS files, indicating my currently uncommitted changes, and integrating Git features like Status and Blame (but that might be a blog post for another time). On top of everything, Sublime Text is made available on Windows, OSX, and Linux, entirely free of charge, though you can choose to support the developer by purchasing it. It is an undeniably valuable tool in any developer’s kit and is a delight to use.

When Creating a Mobile Strategy, Being an Underdog is a Good Thing

When Creating a Mobile Strategy, Being an Underdog is a Good Thing

“Giants are not as strong and powerful as they seem.  And sometimes, the shepherd boy has a sling in his pocket.” – Malcom Gladwell

This September noted provocateur and Evangelist of Everything Outlier Malcom Gladwell gave an excellent TEDx talk on the unheard story of David and Goliath in which he concluded with the quote above.

In it, Gladwell defies convention instead of reinforcing the classic underdog tale of the young shepherd armed only with a sling.  Gladwell asks what the David and Goliath story was truly about and concludes that David was no underdog.  Rather, David was the perfect warrior with the perfect tool to defeat towering opposition and force an army into full retreat.

In part one of this two part series on Creating a Viable Mobile Strategy for Small Business, we’ll discuss why  this is the time to take what seems obvious to you mobile.  In the second post, we’ll focus on how  to get you there.

It’s a Great Time to Be a “David”
When David descended into the Valley of Elah 3,000 years ago, he knew what he was doing.  It was that everyone else was obsessed with conventional thinking to see the utterly predictable coming.  There are many Goliaths still striking terror into the current business landscape, but never has there been a better time to be a shepherd with a sling.

Right now, products like Aereo, Apple TV, ChromeCast and Roku have begun the systematic dismantling of the cable television business.  Don’t believe it will happen?  Just ask the music industry how their hubris allowed web and mobile devices to shrink their business model 64% in less than 15 years.  Even the tallest of giants can come crashing down.

Kings of the Digital Age
Over the last decade, we’ve seen one company go from a trusty search engine into one of the nation’s 50 most profitable businesses.  We’ve seen another go from an idea hatched out of a Cambridge dorm room to over five billion dollars annually.  We’ve just watched a third go public as the de facto SMS of the internet with a market cap of over $25 billion in the last month, all of which have been validated by Wall Street.

In the spirit of Malcom Gladwell, Google, Facebook and Twitter were never underdogs.  They were clearheaded ideas in the face of adversity and marketplaces that already had supposed victors.  Those companies and those ideas were perfectly suited for their time and place and with leaders and a clear vision on how to succeed.

The modern sling of business is reaching customers through the web and mobile technology.  True, not all of us are destined to become kings of ancient Mediterranean civilizations, but small businesses are more capable of taking on anyone now more than ever, if they have the courage to do what they are already doing to pinpoint success.

You have an idea and the industry expertise.  Shockoe can provide the tools to accelerate your idea in the digital world.

Do you have the courage to do what you know will help launch your own digital kingdom?

Shockoe: Contact Us

Page 1 of 812345...Last »