CorvetteDNA for iOS

Previously I noted “the app is submitted, before the Christmas rush”. Well it’s called CorvetteDNA and I developed it with and for a group called CorvetteDNA. We have a big database of Corvette (the car not the boat) facts and pricing computations.

The app lets you price out a Vette from any year with any options, and gives you the current market value. It’s a pricing tool for sellers, buyers, and car enthusiasts.

The submission to the app store made it in time. We had the approval in about 5 days and it was ready for download. Before Christmas we also did 2 other updates in that timeframe and had them approved also with a few changes and bug fixes. That’s pretty good time frame, 4-5 days. That’s what it took Scanning Slideshow to get reviewed in too.

Here’s the preview link for CorvetteDNA

One frustrating thing with the App Store on iPad, is that the app is not designed for iPad. But the iPad App Store app defaults to searching only for iPad optimized apps, even if you search for the exact name of an app,  you don’t get it unless you change a selector to “iPhone apps”.

Scanning Slideshow app now available

My latest desktop app is Scanning Slideshow – an app to show an image display “slideshow”. What makes this unique is that it RESCANS the folder continuously in order to show new images when they show up in the folder.

For example, you are a photographer at a wedding. The couple wants to show images from the ceremony at the reception, right away, on your laptop or projector. And they also want images shot right now, during the reception, in the show. You shoot with your wireless camera (camera with wifi, eye-fi, etc) and send the images to the computer. Use Scanning Slideshow to display the images from the folder where the images are saved. When new images are saved to the folder, those new images are the ones that are shown first.
I had to do some research on this previously and there seems to be no other decent software to actually do this. There is a graphics app that will do it, but the display really stinks and has display update issues, it’s not designed for this. There is another app but it’s Adobe Air based and has a crappy installer and just is a little flakey in general. Scanning Slideshow is 100% Cocoa based and dedicated to just running the show.

It’s got a full screen mode, of course, that can be turned on or off. Maybe you want to test the functionality or just play a little slideshow of images as they slowly download to a folder… maybe you are doing some FTP of files and want monitor them in a tiny window. You get the idea. There are transistion styles with some built in CIFilters, the basic ones that make sense to easily add to the program.

One weird thing is in Mavericks there is a new flag I had to add to the ImageView to use CIFilters. It’s not present pre-Mavs, and has little documentation (not that it’s hard, just enable it). So I had to add an “if responds to selector…” in the code to run it on Mavs.

Click HERE to check it out on the Mac App Store (web preview)

Design for design sake?

I was talking a few days ago with a programming buddy. We both were in the camp that there is, and always has been, a propensity of companies to adopt change (or design change) for design sake. Take Microsoft Word for example, or any MS product. It is a very mature product. It needs few changes for the vast majority of functions, yet MS changes it. My friend’s analysis is that MS sells not just software, but is a publisher- of books, and training seminars, and certification classes. Small UI changes yeilds a whole refreshed revenue stream from users who have updated and then need a guide to all the changes. MS makes money on the software, but also new books, etc.

I won’t argue AGAINST some UI changes or application changes. It’s necessary for advancement and new features, or to utilize new hardware that is truly a benefit (faster connections, higher DPI screens, larger screens etc). But not every change is a benefit. Change can easily outpace the patience of average or less than average users; heck even power users like me get grated when new stuff changes with no visible improvement. Or worse (I’m looking at you, Apple, my buddy), functions and UI elements are ACTUALLY REMOVED, or hidden, or made less useful.

Applications are developed for the users to do work, and keeping people productive and happy should be the primary goal, and reduction of user frustration should be a goal whenever UI or functions change. And for heaven’s sake, a decent user manual!

Submitted

The app has been submitted to the App Store!  Now we have to wait for approval, hopefully I got it in before the “Christmas app rush”.

Admob and No Ads

Failed to receive ad with error: Request Error: No ad to show.

Is the error message I get when I try to run my app with admob included. Well, the one thing that is left out, if you did not actually sign up yourself for admob, is that you have to register the app to actually receive the ads. I am using someone else’s Android app setup and not getting anything but test ads. We have to go into Admob setup and add the iOS version to be able to get ads. Problem solved, too bad Stack didn’t have this information listed.

Github Projects

Recently I’ve had to build a bunch of little iOS test apps for learning and understanding some concepts. And my preference is for a little app that will demonstrate JUST ONE concept at a time. So many Apple sample code projects really compress a lot things into 1 sample. Sometimes it’s good to see complex, sometimes it’s not what you want.
So I give you a couple sample projects.

1. XML Parsing on iPhone
Let’s say you want to parse XML on the iPhone. There are a few less classes to rebuild the XML structure than on desktop. I wanted to be able to recreate the tree structure of an XML document in iOS. This meant having a branch/leaf data object. A class that could hold some simple node data, but also hold the other nodes inside of it. This wasn’t the end goal for what I need to ultimately do with my data, but it was a good way to start.
Check out “WalkerTexasRanger XML Parser” project on Git.
The 3rd version is where I add in the specifcs on parsing out different kinds of data. This is likely what you’d do with it- when you see a “person” object then you’d make a person object and populate that object with subsequent data. There are lots of examples online on doing that, but these 3 take you from a basic tree into more details.

2. Some examples on creating a custom table cell with a XIB/NIB file instead of programmically and NOT using a storyboard prototype cell. Call me old-school, but I didn’t want to use storyboard. The BNR guys said not to. I didn’t to see the storyboard file in my project. Just simple, plain, editable XIB file of a UIView. So after some searching and this demo, thanks, I made this sample project that does that.

On the importance of user focussed UI

Dual desktop metaphors on Win tablets can lead to user confusion. I’ve also been a long time opponent of features or tools that can only be discovered by rolling over an invisible area or other element that does not appear to be a widget.

http://www.useit.com/alertbox/windows-8.html

As seen on daringfireball.com

Applescript: The Marines & Chief Interrogator In 1

Applescript: Much maligned, much beloved. The language itself is considered to be based on SmallTalk or List (? I need to verify that). It’s got it’s nice features in that it seems English like and more readable than almost all other programming languages, even the other scripting ones. But that’s secondary to what it does. I would compare Applescript to the US Marines: It Gets The Job Done. If you need automation (on a Mac), Applescript can do nearly everything. And what it can’t do directly, you can even fudge it to “fake” clicking the menus and buttons of non-scriptable applications.

Chief Interrogator: Here’s where Applescript is sneaky and also makes it one of the most interesting languages. In order to have an application be scriptable, the application designers have to go to significant lengths to expose their underlying framework to Applescript commands. Specifically, they must write getters and setters for their variables in ways that Applescript can use them, and also that won’t interfere with the internal workings of their methods and circumvent other cascading actions that happen when a variable is changed.

“So what” you may say. So what is this: learning how to Applescript any application is akin to looking into it’s inner workings. No 2 applications will do things the same way. InDesign will not use the same method to add a new page to a document the way QuarkXPress does nor the same way Apple Pages or MS-Word will. No 2 FTP application will upload files using the same syntax nor the same methods. I know for a fact that Interarchy will let me simply “send” and FTP command and it will send a file directly from the application, while CyberDuck (I believe) requires that you first have an active window, and tell the window to send a file. There you can see a huge difference in the internals of the design of each application. Interarchy might always show you a window, but it’s sending of a file is not dependent on instantiating a window first. While CyberDuck clearly, internally, must first instantiate a window object, and the file transfer commands must be housed inside of either the window class, or called from the window class.

So, when I am working with an application, I must always consider that I am not just “telling” the application to do something that any application of it’s category would do. No, I have access to the application, and I must sometimes consider that how one developer would word their commands is not the same as another. And it might take great creativity to find out, from usually non-existant documentation, how to properly “talk to” an application to say the magic sequence of commands it will accept.

Applescript isn’t a once-and-done learning experience. It’s learning every OTHER application at the same time too. And then learning updated applications’ new ways to do old functions, or new methods for new features.

Adding Applescript to a Cocoa (Mac OSX) App

How to add some Applescript to your application. This is by no means a comprehensive tutorial, but only a guide I built first for myself and wanted to keep it handy for myself and share it with others. There’s not a lot of information on this topic on the web.

It’s super complex so make sure you do it exactly right. It might take a few test apps to understand it well.

Classes:

You can use a category of your Cocoa object’s base class, because that is simple to handle. Then you can tell your object to “do something” and the implementation of the script can be wildly different than the standard internal methods. But remember there can be no new ivars in the category! This means if you need to get values from the main class then you will need to have a lot of getters/setters in the main class.

@interface MYObjectClass (MYObjectCategoryName)

//method declarations…

-(id)doThisThing:(NSScriptCommand*)command;

 

First example is how to make a method do something.

The method must take a NSScriptCommand value. Don’t put any other parameters here, the NSSC will pass in a bunch of variables, as many as you want, as an NSDictionary.

In your method, do something like this:

-(void)pavsFunc:(NSScriptCommand *)command
{
NSDictionary* theArgs = [command evaluatedArguments];
NSString *inputText = [theArgs objectForKey:@"theText"];
NSLog(@”passed text = %@”, inputText);
}

1. The arguments (theArgs) is the standard way to get all the passed in arguments. Your Applescript could look like

tell myObject
doThisThing first name “Dick” last name “Jones”
end

2. In the method then you have to get each part of the parameters into an ObjC variable. They pass in as one Dictionary. So you need to call out each key from the dictionary. There will be a line for each variable you passed in. Such as:

NSString *theFirstName = [theArgs objectForKey:@"firstName"];
NSString *theLastName = [theArgs objectForKey:@"lastName"];

You can see that the KEY name does NOT have to match any particular variable name in your code. You can pass about variable names as you normally would in ObjC. But you will need to match up the key name in the SDEF file later.

3. The SDEF file is the Rube Goldberg-esque construct that will link Applescript to Cocoa. Use SDEF Editor if possible, but it’s also handy to edit the XML directly. Add a Suite for your application, and give it a code. Adding the Suite is pretty basic. There’s no direct link from the suite to any particular class files.

For simple applications, you would add just one suite for all your commands, like “MyApp Suite”. Extremely complex applications (think InDesign, Photoshop, MS Entourage) can have multiple suites, because each one does something different. For example, InDesign has a suite just for Layout (the primary way to manipulate page elements), and also one for Color (to create and edit swatches, colors, gradients etc), and about 18 others.

Now there are several conceptual levels in the SDEF. The CLASSES will let you designate one of your ObjC class files as something scriptable. You can give it a name that is different from the actual Cocoa class name in your code/project. So you can have “rectangle” as the script object but the class it works on is “CPRectangle”.

4. Add a command to the class object. Give it a name. This name will be the same as the name used for Suite > Commands. It must be the same in order to link up. Set the Cocoa Method to what method this actually runs, like: -(void)pavsFunc:(NSScriptCommand *)command. See image below.

So far we’ve simply added information to the SDEF that says “class rectangle responds to a command “rotate” and it calls the actual Cocoa method “pavsFunc:”

5. Now we have told the class what command it can understand, we have to add a part that tells Applescript what commands are available. Under the Suite > Commands folder, add a new command. Give it THE SAME NAME as your command for the class. Give it an interesting code, and some descriptive text so you know what it does. I think there’s a limit to the amount of text that can be displayed. Since we are working on a 1 to 1 relationship with this command, don’t add anything for Cocoa name or class here. (Cocoa Name and Cocoa Class are used for verb-first scripting; what we are making here is object first scripting.)

6. A direct parameter *must* be added in order for the command to be used by a class. So for example, the command “invert selection 1″ has the direct parameter of “selection 1″, the command is “invert”. It must be the class for the command or superclass.

 

7. Parameters are the other values passed to the command. The name is what you’ll call it in the actual Applescript. The code should not conflict with other codes nor Apple’s. The type is what kind of data this is, and may include objects of the same or other classes, not only text or numbers. Description is obviously for humans to read and for your documentation. Cocoa Key (see image below) is the value that will be used to make the dictionary of data that the Cocoa method must pull out from the Argument, like this: NSString *theFirstName = [theArgs objectForKey:@"firstName"]; (and in the Name part call it “first name”, ie: doThisThing first name “Dick”)

You can add any number of parameters and some can be optional. Be sure to handle optional parameters properly in the Cocoa code.

It’s not easy to have a command without a direct parameter– that requires whole new classes (look up verb-first in the Neuberg book). Really every command is handled inside of some “tell something…” block. The TYPE of the direct parameter is the name of the class in SDEF editor. Your class “CPRectangle” may be named “rectangle” in SDEF, so pick that from the popup list.

The commands should be good now.

 

The flow of command logic is something like this, in a very abstract and non-technical way:

 

1. An Applescript command is given by a script or editor.

2. The script calls a certain function/command you defined, along with any of its indirect parameters.

3. The command name then matches itself to the class command by name, and then the parameters dictionary is passed into the Cocoa method of the class object.

4. Then the Cocoa method is called and fired. If a dictionary was passed in, then the Cocoa method has to extract each dictionary item by NAME (ie Key) only, and then can do something with it, like setting a variable to the key value it scanned.

5. Potentially the Cocoa method returns something and that gets passed back to Applescript. That’s outside of my current tutorial at this point.

Desktop Blurrifier is out and munching on wallpapers

My 2nd big app “for everybody” is available to the Mac using public now. I’ve wanted to make this little app for YEARS now. There was a guy who made a spiffy app to do “multiple image wallpapers”. But I don’t think he ever kept up with it. I have a beta version of that, but I couldn’t convince him to add blurring or that would have been nifty.

So my app does exactly what I want, and come to think of it, can also handle making a desktop drawn across multiple screens from 1 image.

Desktop Blurrifier makes any image a little blurry. It scales up, or down too, and can reposition horizontally or vertically. One really cool thing is that I made the scale slider do a non-linear scale. So 1/2 of the slider scales from 0.1 to 1.0; the other half scales up as a square of the value, from 1.0 to 4.0. It also “snaps” to the middle tick slider with a bit of code. My biggest hurdle on this app was learning how to deal with CIImage class. The examples Apple supplies, the Core Image Fun House app, is fantastic in its own right; but MF! it is so efficient and dense I could not figure out for the life of me how any of it works. Really the point of sample code is to usually show an example of 1 or 2 or maybe 3 concepts. Well this one has every CIImage filter included, plus procedural UI elements! There was another sample I looked at, ImageExample I think, and that was easier to understand but had some color management code completely woven into it that I couldn’t just cut and paste code. Which is generally all the better in the end, but of course frustrating when it doesn’t make sense. I did end up with a reasonably elegant solution for my filter objects, with cues taken from that sample code. Performance was always good on my coding machine, but my wife’s older laptop showed some noticeable lag. Well, it’s not supposed to be Photoshop so I wasn’t going to try to change it much.

I also had fun putting some drag and drop code in, which includes a big fat red stroke when a new image is dropped. One frustrating correction I had to make at the very end was dealing with multiple Space in 10.7 Lion. Lion’s spaces EACH can have different desktops AND can also have changing images as well. The changing image option was a real pain to deal with, as I never used it and it didn’t occur to me until my beta test group (thanks MacDeveloper.net) brought it up to me. I had to sort of hack in a check where if an image failed to load in 2 different ways, then I’d assume the Change Image option was on and then had to dump out to an error dialog. When the change image option is on, the current desktop isn’t actually returned as a picture, it’s returned as a FOLDER URL. And there is no option to know specifically that the option is on, you just have to see if it’s a folder or image URL. Using the set desktop method though, will simply turn this option off. So after I warn users, they can still set a picture, and BAM it’s on. But their rotating image won’t continue to rotate, that would have to be turned back on. Oh well, maybe a preference for another version eh?