Monday, April 30, 2012

Reminder: Set the Application Identifier in your Web App

Many times when a web app won't run, it's the simple things like setting an Application Identifier that are causing the trouble. Your web application must have an Application Identifier specified on the App properties or the web application will not start.

The Application Identifier can be set in three simple steps:

1. Click on the Project tab
2. Select the App class
3. Edit the Application Identifier property

The format usually looks like this:


You can find more details on the Application Identifier at our Documentation Wiki:

Friday, April 27, 2012

Real Studio Refactoring Tips

Did you know that Real Studio has a bunch of refactoring features that can help make you more efficient?  Let's take a look at them.


When you access the contextual menu of a class (right-click or control-click on OS X), you'll see these two features in the menu: New Subclass and Extract Superclass.

New Subclass
Click on New Subclass and Real Studio creates a new class in your project that automatically has the selected class set as its Super.

Extract Superclass
The Extract Superclass feature opens a dialog that lets you choose the methods and properties to extract from the selected class and move to a superclass.  The selected class also gets its Super set to the newly created super class.
Extract Superclass Dialog

With the Code Editor open, you can see refactoring features when you view the contextual menu for methods and properties.

With a regular method selected, you will see Convert to Shared.  This feature converts the method from a regular method (an instance method) to a shared method.  If you were to right-click on a shared method then you would instead see Convert to Regular which does the opposite.

Properties have a similar feature to Convert to Shared or Convert to Regular.  In addition they have Convert to Computed Property.  This feature will take your current regular property, rename it with an "m" at the beginning, make it private and then make a public computed property that uses the regular property as its back end storage for the Get and Set components.

Code Editor

When you are editing code, the contextual menu has several useful refactoring features.

Wrap in If/End If
This takes either the current line of code or the current selection and wraps it in an If..Then/End If block.

Wrap in Do/Loop
As above, but wraps it in an Do..Loop block.

Wrap in While/Wend
As expected, wraps it in a While..Wend block.

Convert to Method
This feature takes the current selection and moves it to a method for you and then takes you to the method where you can specify the name and parameters.  Don't forget to go back to the original code and add the method call, though!

Convert to Constant
Takes the selected text and moves it to a constant definition.  The name of the constant is the name of the selected text.  Real Studio replaces the selected text with the newly created constant name.  This is very handy for localizing as it makes is quick and easy for you to move hard-coded strings to constants.

Define Missing Method
When I write my code, I often will type a method name that I expect to use even though it doesn't actually exist yet.  I can then go back, select the method name and choose Define Missing Method to have Real Studio create the method definition for me.  In order for this option to be enabled, you do have to select a method that has parenthesis even if there are no arguments.  So Calculate() works but just Calculate does not.

Standardize Format
This is my favorite feature.  I use this all the time. It takes the selected block of code and applies consistent formatting to it.  There is nothing that I hate more than source code that has inconsistent naming.

Inconsistent capitalization drives me nuts:
dim i as Integer

It should be:
Dim i As Integer

or at the very least this, even though I don't like all lowercase:
dim i as integer

Standardize Format keeps me sane!

Properly Formatted Code

I hope one of these features will help make your development more efficient!

Thursday, April 26, 2012

Third Party Products and Community Resources

I am pleased to announce that we have added two new sections to the Documentation Wiki:

Third Party Products and Community Resources

Third Party Products is a list of products that work with Real Studio, grouped by type.  There are a lot, perhaps more than you think!  And if you come across anything that I may have missed, please let me know.

Community Resources is a list of useful information that is related to Real Studio and programming with Realbasic.  This could be community member blogs, sample code or both.

I hope you find these new pages useful and again, if you notice anything I've missed, please let me know.

Wednesday, April 25, 2012

Unlimited Employee Vacation Policy

I ran across this story in Mashable last week about Netflix's unlimited employee
vacation policy. We've been operating with a similar policy since 2010 with great
results. Switching to a virtual office model – as we did in 2008 – forces a company to
put more trust in its employees. When you can no longer literally "keep an eye" on
everyone around the office, you end up rethinking a lot of your policies. Previously, each
employee was given a set number of paid time off (PTO) days each year, but we felt like
this traditional office practice didn’t fit into our modern, flexible culture.

Our current policy – like Netflix’s – doesn't set any limit to the PTO an employee can
take each year. Instead, employees are encouraged to take the days they need,
when they need them. Geoff is quick to share our success with this change, saying, "I
encourage people to take time off when they need it. What I don't want is people taking
time off arbitrarily because they think if they don't, they’re losing something."

Personally, I like being part of a company that treats us like adults and embraces
this “freedom and responsibility culture.”

Thursday, April 12, 2012

The Importance of Being Earnest

Real Studio, or to be more exact the Realbasic language, has made it to the "Next 50 Programming Languages" in the TIOBE Index this month. For those of you not familiar with this index, TIOBE stands for The Importance of Being Earnest and is meant to be a reflection of the language with the most lines of code written, not the "best" language. TIOBE uses popular search engines like Google, Bing, Yahoo!, Wikipedia, Amazon, YouTube and Baidu to calculate their ratings (visit them here for details on exactly how they determine TIOBE ratings).

To quote TIOBE, "The TIOBE Programming Community index is an indicator of the popularity of programming languages. The index is updated once a month. The ratings are based on the number of skilled engineers world-wide, courses and third party vendors." We don't use the term Realbasic often, but it is important to realize that it is the name of Real Studio's programming language.  If you're writing about the programming language, try to use Realbasic to describe it.

A special thank you to Kevin Cully, founder of the Real Studio Atlanta Group, for pointing out Realbasic's rise in the April Index.

Video: Building a Simple Web Application

Our newest tutorial video is now available at our YouTube Channel:

Real Studio QuickStart: Creating a Web Application

In this video, I describe how to create MapViewer, a simple Real Studio web application that displays map locations.

Monday, April 9, 2012

The importance of feedback...

Over the last few nights, I've been watching the screencast of the SolarUG meeting from March 29th which was pretty much dedicated to the Real Studio web framework. I was unable to attend in person, but was still curious about what had been discussed.

Somewhere in the middle of the meeting, a comment was made about how slow the WebListBox gets when you send lots of rows (like 1000 rows of 150 characters each). My immediate reaction was "well yeah, that's a lot of data," but the user seemed sure that the delay was after the data got to the browser, so I decided to take a second look.

The Diagnosis

All of the major browsers that we support (except IE7) have a built-in profiler (like the one in Real Studio) that lets you see how many times a method was called, how long each call took and the total time ( # of executions multiplied by call time), which can be incredibly useful in figuring out why something is running slowly. 

I created a simple web app which had a single listbox, and in WebPage1.Shown, I called Listbox1.AddRow 1000 times inserting a 190 character text sample. Running this app locally, creating and sending the rows was nearly instantaneous, but then the WebListBox took 2.83 seconds to draw. Yikes! Time to dig deeper.

The Bug

After a little experimentation, I discovered an issue with the rendering routine that goes something like this:

  1. Adding the first row refreshes the first row
  2. Adding the second row refreshes row 1 and 2
  3. Adding the third row refreshes row 1, 2 and 3
  4. …and so on…
If you do the math, the number of individual row refreshes is a little over 500,000. Several other methods are also called from this procedure, each adding to the severity of the bug.

The Fix

In Real Studio 2012r1, changing the contents of a WebListBox now employs a delayed refresh. Basically, if you send a bunch of commands to add or remove rows, the refresh is now delayed until the set is complete. The browser spends less time refreshing rows and gets the data to your end user faster!

…and the moral of the story is…

As far as I can tell, this bug was not in Feedback. In other words, no one has ever reported it. If you notice a web framework control that doesn't seem to perform as well as you expect it to, LET US KNOW! File a bug report in Feedback with an example and don't assume that it's that way just because it's a web app.

Tuesday, April 3, 2012

Secure Web Edition Login Screens

As Real Studio web edition matures, more and more customers are using it to create applications that may contain private end-user information. This means that it's becoming increasingly important that your web applications be protected with an SSL certificate and some kind of authentication to make sure the user is who they claim to be.

Note: To follow along, you will need to build a CGI application and run it on a server that has an SSL certificate installed. Otherwise, you'll get an error.

Traditionally, a login screen requests a UserID of some kind (whether an email address or other unique identifying identifier of some kind, like an account number) and a password (automatically generated or entered by the end-user).

Example of a simple login screen.

My favorite method for creating login screens in Real Studio web edition is to use a Modal Dialog on an otherwise empty page, because there is no question about what you need the user to do next. It also allows you to deal with the complexities of the login process without any other code possibly getting in the way.

Something to remember: SSL connections are notably slower than non-SSL connections because no caching is allowed, so you might not want your whole web application to be secure (like if you were creating a publicly accessible site with special features for members-only). What you need to be able to do is to switch from non-SSL to SSL when a user gets to the login screen.

Making the Switch

In the example given above, the login screen is simply a blank web page that shows a web dialog in the Shown event. Before you get to that point, you need to check to see if the connection is secure. In the LoginPage.Open event:

Sub Open()
  // Make sure the user is connecting securely,
  // If not have the browser load the application securely
  if not session.Secure then
    dim host as string = session.Header("Host")
    dim url as string = "https://" + host
  end if
End Sub

Okay great, but this will take the user back to the initial entry screen, not the login page, so we need to tell the session how to handle that. In the WebSession.Open() event:

Sub Open()
  If Self.Secure then
  end if
End Sub

In this case we're making the assumption that an end-user that is just connecting to the app (i.e. creating a new Session) and is connecting securely will want to be directed to the login page.

Remember Me

If you look at the screen shot, I've included a "Remember Me" checkbox. Typically these are used to remember the UserID to help jog the end-user's memory about what their password might be. This function uses a browser feature called Cookies which stores a snippet of information on the computer where the user is (assuming cookies are enabled, of course). NOTE: I suggest not remembering the user's password because if this box gets checked on a public computer (like a Library or Internet Cafe) the user's account could be compromised.

To make the checkbox work, we need two pieces of code – in LoginPage.Shown:

Sub Shown()
    if session.Cookies.Value("username") <> "" then
      username.text = session.Cookies.Value("username")
      rememberme.Value = true
    end if
End Sub

First, we check to see if the "username" cookie has been set, and if it has, the value is placed into the Username text field, the RememberMe checkbox is checked and the focus is set to the Password field (mostly a convenience to the users don't need to do that manually).

Next, in the Action() event of the Login button:

Sub Action()
End Sub

Then create a method:

Sub DoLogin()
  if rememberme.Value then
  end if

End Sub

You may be asking yourself why I've created a separate method for what would normally be in the Action event… because you may want to close this dialog from another location (see below), but first, when the user clicks the login button, we check the value of the RememberMe checkbox – If True, we set the Username Cookie to the value in the username.text field. If False, we remove the cookie (otherwise user's wouldn't be able to remove the cookie by unchecking the box)

Capturing Returns

One last thing. Users expect things to work just like all the other web applications out there, and that means that when they press the Return key on their keyboard, they usually expect the login action to occur. You can do this by adding code the the KeyPressed event of the window itself:

Sub KeyPressed(Details As REALbasic.KeyEvent)
  if details.KeyCode = 13 then
  end if
End Sub

This is why we put the code from the Action event into a separate method! Now, when the user types their username and/or password and hits the Return key, the dialog will be dismissed just as if they had clicked the Login button themselves!