Category Archives: Development

Objective-C Literals with Data Abstract

Xcode 4.4 introduced Objective-C Literals which I think are great. Objective-C Literals are a collection of language enhancements that make it possible to do many common practices and patterns in Objective-C by writing less code. This includes boxing numbers, working with arrays and working with dictionaries. For instance, here’s some sample code for writing and reading an array without using Objective-C Literals:

[array setObject:@"one" atIndexedSubscript:0];
[array setObject:@"two" atIndexedSubscript:1];
[array setObject:@"three" atIndexedSubscript:2];

NSLog(@"%@", [array objectAtIndex:0]);
NSLog(@"%@", [array objectAtIndex:1]);
NSLog(@"%@", [array objectAtIndex:2]);

Here is the same code, now using the new enhancements for working with arrays:

array[0] = @"one";
array[1] = @"two";
array[2] = @"three";

NSLog(@"%@", array[0]);
NSLog(@"%@", array[1]);
NSLog(@"%@", array[2]);

Xcode even includes a refactoring called Convert to Modern Objective-C Syntax that will help you convert most of your code to this newer format.

Data Abstract, a multi-platform library for data access by RemObjects Software, also supports this new syntax when dealing with rows of data. The syntax was added to Data Abstract, according to Marc Hoffman, right after the Objective-C Literals support was announced at WWDC. Here is an example of working with a row of data before this change:

[row setValue:@"one" forKey:@"firstColumn"];
[row setValue:@"two" forKey:@"secondColumn"];
[row setValue:@"three" forKey:@"thirdColumn"];

NSLog(@"%@", [row valueForKey:@"firstColumn"]);
NSLog(@"%@", [row valueForKey:@"secondColumn"]);
NSLog(@"%@", [row valueForKey:@"thirdColumn"]);

And here is the newer syntax:

row[@"firstColumn"] = @"one";
row[@"secondColumn"] = @"two";
row[@"thirdColumn"] = @"three";

NSLog(@"%@", row[@"firstColumn"]);
NSLog(@"%@", row[@"secondColumn"]);
NSLog(@"%@", row[@"thirdColumn"]);

Fantastic I think! Easier to write, easy to read, and a very consistent and familiar way to access data by subscript. However, there is no built in refactoring in Xcode to change your old DADataTableRow code to this new format.

Stuck doing this by hand? I think not!

You can migrate your code to the newer syntax using Xcode’s Find & Replace. The Find & Replace in Xcode supports two powerful features we’ll use here: Regular Expresion (Regex) patterns and being able to preview and reject changes one-by-one.

To get started, load up your project in Xcode. On the left, select the Search Navigator (or press ⌘3). At the top of the Navigator, select Replace if Find is selected. Click the magnifying glass with the down arrow to the left of the search box and click Show Find Options. Under Style, select Regular Expression.


To replace the instances of code where values are being written, use the following search pattern:

[(.*) setValue:(.*) forKey:(.*)];

And use the following replace pattern:

1[3] = 2;

To replace the instances of code where row values are being read, use the following search pattern:

[(.*) valueForKey:(.*)]

And the following replace pattern:

1[2]

Click the Preview button to preview changes first. You can use the sliders in the middle of the preview window to accept and reject individual changes.


Once you’ve reviewed the changes, click Replace and you’re done! I’m happy any time I can use Regular Expressions without ending up with more problems than I started with.

Help Localize Hip Shot


I’ve finished the work necessary to make Hip Shot available in any language that iOS supports. I’ve updated the homepage with a couple of links in the footer for those who can help translate a few words and phrases. As I receive translations I’ll update the footer to include those languages no longer needed.

Hip Shot is designed to help those who suffer from Multiple Sclerosis track their medical injections without having to resort to pen and paper. It is in use by folks world-wide and proceeds are donated to the National Multiple Sclerosis Society. If you have the time and ability, please take a few moments to translate these few words and phrases into a language you know and send them here.

Releasing the Source of a Simple Application Framework

A few years ago I blogged about, and made available on a smaller scale, a simple application framework built using RemObjects Hydra and the DevExpress WinForms controls called tide. I’ve taken some time to clean up the source code and the licensing, as well as getting the project working using the latest RemObjects and DevExpress releases.

The result is now available on Bitbucket. The source code includes a sample based on the Northwind database and the Wiki includes links to several articles on creating the Northwind sample.

SimpleDrawing 1.1 Available on the App Store


Version 1.1 of SimpleDrawing is available for free on the Apple App Store. This update brings a few bug fixes, along with a bucket tool and a brush tool. The brush tool has several patterns available.

SimpleDrawing is an open source drawing app for iOS. The latest source code for SimpleDrawing, including the changes found in version 1.1, is available on the public Git repo.

What’s New in Version 1.1
• Added a bucket tool
• Added a paint brush tool with multiple patterns
• Show individual drawing titles on the initial screen
• Show the name of the current drawing tool on the iPad
• Added new settings
• Improved alignment of controls on the iPhone 5
• Fixed bug: cannot redo text tool after undoing
• Fixed bug: photos traced have double transparency
• Fixed bug: app may allow landscape orientation on the iPad

Displaying the XtraScheduler Context Menu Programmatically

The XtraScheduler product from DevExpress is suite of flexible and powerful calendar controls. The scheduler control itself has a built in popup menu that displays context sensitive items when the end-user right-clicks the control.

However, it’s not immediately obvious how to display this menu, with the appropriate context options, programmatically. For instance, you may have an XtraGrid control setup synchronized with the XtraScheduler control. It would be pretty sweet if right-clicking an appointment in the XtraGrid control displayed the appropriate XtraScheduler context menu.

With some digging through the XtraScheduler classes, comments, and some trial and error, I was able to come up with the following working code:

        private void gridControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                SchedulerHitInfo hitInfo = new SchedulerHitInfo(SelectableIntervalViewInfo.Empty, SchedulerHitTest.AppointmentContent);
                WinFormsSchedulerMenuBuilderUIFactory uiFactory = new WinFormsSchedulerMenuBuilderUIFactory();
                SchedulerDefaultPopupMenuWinBuilder builder = new SchedulerDefaultPopupMenuWinBuilder(uiFactory, schedulerControl, hitInfo);
                IDXPopupMenu<SchedulerMenuItemId> popupMenu = builder.CreatePopupMenu();
                ((IDXDropDownControl)popupMenu).Show(schedulerControl.MenuManager, (Control)sender, new System.Drawing.Point(e.X, e.Y));
            }
        }

The first line creates a new instance SchedulerHitInfo with SchedulerHitTest.AppointmentContent specified as the element under the hit info. This controls which menu contents will be displayed. In this case, the menu contents shown when right-clicking an appointment are displayed.

The next three lines create the popup menu itself by using a WinFormsSchedulerMenuBuilderUIFactory and WinFormsSchedulerMenuBuilderUIFactory.

Finally, the last line displays the popup menu itself. The first parameter is an IDXMenuManager, which can be accessed via the MenuManager property of the scheduler control. The second parameter is the parent control for the popup menu. The final parameter is the position for the popup menu within the parent control.

Together, these lines allow you to display the XtraScheduler menu, with the appropriate context sensitive contents and at any position, from code. Hopefully this bit of code comes in handy as these classes aren’t currently (well) documented. Enjoy!

SimpleDrawing Available Free on the App Store

A week ago I posted about SimpleDrawing, an open source drawing app for iOS that I created. The app is now available for free on the Apple App Store, which makes it super easy to try out before deciding to dig into the code.

This lowers the bar for trying out the finished product while also demonstrating that the techniques used and final product will pass the App Store submission process. And it’s also yet another fun, free drawing tool for the platform!

SimpleDrawing for iOS


Introduction

As the name implies, SimpleDrawing is a simple open source drawing app for iOS. I created SimpleDrawing to serve as an example of how to handle the basic drawing features on an iOS device, including:

  • Tools such as pen, line, text, rectangle, ellipse, and eraser
  • Individual tool settings such as primary and secondary color, line width, transparency, and font size
  • Importing photos from the photo album
  • Multi-level undo and redo operations
  • Layers with individual levels of transparency
  • Sharing via mail, Twitter, camera roll and more

The drawing functionality of SimpleDrawing can be used within your own applications with minimal effort. The design of the code also makes it easy to add your own tools by inheriting from SDDrawingTool and overriding (usually) only one method.

Installation

It is possible to use the drawing functionality of SimpleDrawing within your own project. First add the contents of the SimpleDrawing project directly to your Xcode project by drag-and-drop. Next, add the required frameworks: Quartz, Twitter, and MessageUI. Select the main.m file from SimpleDrawing and uncheck it’s “Target Membership” for your target in the File inspector. Finally, disable ARC using the -fno-objc-arc flag for the files BGRSLoupeLayer.m, BSBrightnessSlider.m, and RSColorPickerView.m.

Usage

Once the required files are included in your project, with just a few lines of code you can display a view that lets you browse and create new drawings:

//instantiate the view controller
NSBundle *bundle = [NSBundle bundleForClass:[SDDrawingsViewController class]];
UIStoryboard *storyboard;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    storyboard = [UIStoryboard storyboardWithName:@"SDSimpleDrawing_iPad" bundle:bundle];
} else {
    storyboard = [UIStoryboard storyboardWithName:@"SDSimpleDrawing_iPhone" bundle:bundle];
}
SDDrawingsViewController *viewController = [storyboard instantiateInitialViewController];

//present the view controller
[self presentViewController:viewController animated:YES completion:nil];

Using the SDSimpleDrawing_iPad storyboard presents the user with a suitable iPad UI:

You can download the source code for SimpleDrawing at my repository here.

UPDATE: The SimpleDrawing app is now available for free from the Apple App Store if you want a free and easy way to try the app.

Releasing the Source of VCL Controls based on DevExpress Look & Feel

The “cx-tras” package is a set of components I created nearly ten years ago and have been maintaining since. It is a set of visual components for Delphi that support DevExpress’s Look & Feel technology. This means that they automatically adjust their look based on the appearance and skin settings used in DevExpress VCL applications. The components were originally distributed by myself on request, then by DevExpress Support for a time, and now I’m giving them a home where anyone can access the source.

Various configurations for the Office Gizmo control

Demonstration of the Text Flow Panel control

Examples of the Close Button, Expand Button, and Size Grip

You can now access the source for the cx-tras package on Bitbucket here.

FileSystemView for iOS Developers

Introduction

When developing an iOS application with persistent data, having an easy way to browse the file system from within the app can be very beneficial. It’s possible to view files in Xcode Organizer with your device tethered via USB, and it’s possible browse the OS X file system to view files created in the simulator. However, having a view that can be tailored to show your application-specific directories available directly within the app is far more convenient. That’s where FileSystemView comes in.

Installation

FileSystemView is easy to include in any iPhone, iPod or iPad project. Simply add the contents of the FileSystemView project directly to your Xcode project by drag-and-drop. Specifically you’ll need to include the contents of the Views, ViewControllers, and Categories directories.

Usage

Once the required files are included in your project, with just a few lines of code you can display a view that lets you navigate the file system at a custom root path, and with a custom starting path:

//instantiate the view controller
NSBundle *bundle = [NSBundle bundleForClass:[FSDirectoryViewController class]];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"FSFileSystemView" bundle:bundle];
UINavigationController *navigationController = [storyboard instantiateInitialViewController];
FSDirectoryViewController *viewController = (FSDirectoryViewController*)navigationController.topViewController;

//set properties on the view controller
viewController.rootPath = [self drawingsDirectory];
viewController.rootPathTitle = @"All Drawings";
viewController.startingPath = [self photoDirectory];
viewController.navigationItem.title = @"Drawing Contents";

//present the view controller
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

    [self.popoverController dismissPopoverAnimated:YES];
    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:navigationController];
    [self.popoverController presentPopoverFromBarButtonItem:self.folderViewButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

} else {

    [self presentViewController:navigationController animated:YES completion:nil];

}

The view shows file counts and file sizes, including recursive counts for directories. In addition the view lets you drill down into sub-directories, navigate to a customizable root path, and view individual file details.

You can grab the source code from my Bitbucket repo here.

UPDATE: The repository was incorrectly setup when I originally posted this. The repo was public but the wiki (which is the landing page) was private. That is resolved now and the repo should be publicly accessible.

Creating Windows 8 Apps with the DXTREME Preview


A couple of weeks ago DevExpress released a preview of their new “multi-channel” solution: DXTREME. In their own words, “multi-channel means building applications that span devices and optimize the best parts of each platform”. If you haven’t already, I highly recommend taking a look at the information they’ve made available on their website. DXTREME is a great solution for creating HTML5 based applications for the web, iOS, Android, Windows Phone 8 and Windows 8.

While the current preview ships with support for creating apps for iOS, Android, and Windows 8, the tooling in Visual Studio does not currently support creating new DXTREME Windows 8 applications. Luckily the DXTREME preview does ship with the comprehensive DXTravel demo, which I was able to analyze in order to determine how to get started with a DXTREME Windows 8 application.

This blog post is going to be based on the MyTrips application created in the Getting Started section of the Learning Center. You can either take a moment to go through the Getting Started tutorial, or you can download the completed MyTrips app (prior to adding Windows 8 support) here.

With the MyTripsApp solution open, add a new project to the solution. In the Add New Project dialog, select Other Languages>JavaScript>Windows Store>Blank App.

For the project name, enter MyTripsWin8App, and click OK.

Add the following folders to the new Windows 8 project, mirroring the DXTREME project structure: data, layoutsNavBar, and views.

Open both the default.html file in the Windows 8 project and the App.html file found in the DXTREME project. Copy the JS, CSS, and HTML references found below the Framework, Layouts, and Views comments and paste them into default.html under the existing code in the head section.

The references found below the Framework comment are the CSS and JS files required to make the DXTREME magic happen. These include both jQuery and KnockoutJS as well as the DXTREME JavaScript and CSS. Also included in this section is db.js, which houses the DXTREME model, and App.css and App.js, which can both be discarded (as they are specific to the original DXTREME project).

    <!-- DXTREME Framework references -->
    <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="js/knockout-2.1.0.js"></script>
    <script type="text/javascript" src="js/globalize.js"></script>

    <script type="text/javascript" src="js/dxtreme.core-12.2.0.js"></script>
    <script type="text/javascript" src="js/dxtreme.framework-12.2.0.js"></script>
    <script type="text/javascript" src="js/dxtreme.widgets-12.2.0.js"></script>
    <script type="text/javascript" src="js/dxtreme.viz-12.2.0.js"></script>

    <link rel="stylesheet" type="text/css" href="css/dxtreme-12.2.0.css" />

    <!-- DXTREME Model references -->
    <script type="text/javascript" src="dataDb.js"></script>

The references found below the Layouts comment refer to the CSS and JS files that make up the various layouts used in the DXTREME application:

    <!-- DXTREME Layout references -->
    <link rel="stylesheet" type="text/css" href="layouts/Navbar/NavbarLayout.css" />
    <link rel="dx-template" type="text/html" href="layouts/Navbar/NavbarLayout.html"/>
    <script type="text/javascript" src="layouts/Navbar/NavbarLayout.js"></script>

These layouts are named (using the data-name attribute) and can then be employed in the DXTREME application in one of three ways:

  1. A layout with the name “default” will automatically be used
  2. An application-wide layout can be specified using the defaultLayout property on the HtmlApplication app object (instantiated in App.js or default.js)
  3. Each view can specify a layout (in the view’s corresponding HTML file) using the data-layout attribute

The references found below the Views comment refer to the CSS, JS, and HTML that make up each view in the DXTREME application.

    <!-- Views -->
    <script type="text/javascript" src="views/Index.js"></script>
    <link rel="dx-template" type="text/html" href="views/Index.html"/>
    <link rel="stylesheet" type="text/css" href="views/Index.css"/>

    <link rel="dx-template" type="text/html" href="views/About.html"/>

    <script type="text/javascript" src="views/TripEvents.js"></script>
    <link rel="dx-template" type="text/html" href="views/TripEvents.html"/>

Now, with the references added to default.html, add the DXTREME JS and CSS files to the Windows 8 project. To do this, right-click the css folder in the MyTripsApp project and click Open Folder in File Explorer. Drag the CSS files to the css folder in the MyTripsWin8App project. Follow the same steps for the js folder and its contents.

Next, add the MyTripsApp views (HTML, JS, and CSS) and model (JS) as links in the MyTripsWin8App project. Right-click the data folder in the Windows 8 project and click Add>Add Existing Item. Browse to the data folder in the MyTripsApp project and select db.js. Click the drop-down arrow on the Add button and click Add As Link.

Repeat these steps for the contents of the views folder and the layoutsNavbar folder.

In order for the images used in the app to show properly, add flight.png and marker.png found in the MyTripsApp/images folder to the MyTripsWin8App/images folder.

Now open up the default.js file in the Windows 8 project. At the top of the file, add the following code:

window.MyTripsApp=window.MyTripsApp||{};

The MyTripsApp above should match whatever DXTREME project you are adding Windows 8 support to. Next, add the following code under the call to app.start():

    // added to support DXTREME
    function startDevExpressApp() {
        DevExpress.ui.initViewport();

        var app = MyTripsApp.app = new DevExpress.framework.html.HtmlApplication({
            ns: MyTripsApp,
            viewPortNode: document.body,
            themeClasses: "dx-theme-win8phone",

            // below copied from App.js in DXTREME project
            defaultLayout: "navbar",
            navigation: [
                new DevExpress.framework.Command({
                    title: "Home",
                    uri: "Index",
                    icon: "home",
                    location: "navigation"
                }),
                new DevExpress.framework.Command({
                    title: "About",
                    uri: "About",
                    icon: "about",
                    location: "navigation"
                })
            ]
        });

        app.router.register(":view/:id", { view: "Index", id: undefined });

        app.navigate();
    };

Compare this code to the code found in the MyTripsApp App.js file. They are very similar, with minor differences for the Windows 8 JS project. You can find more documentation on the application object here.

With these changes in place, you can now run the Windows 8 project and see the trips listed, with links for the Trips and About screen. Clicking a trip shows the trip’s events with a back button to return to the trips list.

You can download the full sample solution with both mobile and Windows 8 projects here.