Mar 22

FMDatabase

Coding, Seasonality Comments Off

Gus posted a very cool SQLite Objective-C wrapper, complete with sample code. It looks like the methods he has in there are pretty handy. Seasonality uses SQLite as it’s database engine, though at the time I was developing it, the only good wrapper I found was for SQLite 2.8.x, so I went for that. I might end up switching to SQLite 3 in a later version, but we’ll have to see. Since the database files are a completely different format between SQLite 2.8 and SQLite 3.x, there would definitely be some work involved in the upgrade.

I figured this would be a good opportunity to talk more about the database aspects of Seasonality. Seasonality actually uses 2 SQLite databases, one of them is the location database in the application bundle, and the other is stored in the users Application Support directory (~/Library/Application Support/Seasonality). The database in the application bundle is really only used as a read-only database, and it contains all of the locations and their associated data values. When you start typing in a zip code to add a location in Seasonality, the app is actually just running a quick SELECT query from the string you’ve typed so far. There are a few different tables in the location database to associate zip codes to ICAO weather locations and radar locations, but overall it’s a pretty simple database. This is actually a subset of all the data that I’ve mined over the past several months…the master is residing in a PostgreSQL database on one of my servers here, and I wrote a Perl script to select subsets of the data from Postgres and insert them into a new SQLite database to include in Seasonality.

The second database in Application Support is used to store all the saved weather data. There are several fields that are saved for future functionality if needed. Other than the temperature, dewpoint, wind and gust speeds used for the graphs right now, Seasonality saves the air pressure, relative humidity, and the visibility along with the date that data is associated with. This brings up a minor complaint of mine…SQLite is typeless, which means that it treats all values you put in the database as the same type. Integers, Floats, and Dates are all inserted as simple strings. They claim this is a feature, but when it comes to date processing it’s a major pain.

When selecting data to build a weather graph, I want to select data that is between two dates. Unfortunately, if I just use a standard date string like Tue Mar 22 22:45:16 EST 2005, it will choke when I try to do a date comparison because it will look at it as a string and, for example, Fri Mar 25 22:45:16 EST 2005 would be seen as happening before the first date because F in Fri is alphabetically before T in Tue. One way around this is to use a very large integer for the date string: 20050322224516. This works fine, and is the method that Seasonality uses to keep track of dates, but it’s slightly inconvenient because all values are above 2^32, so you need to remember to use 64 bit integers to pass dates in and out of the database.

Back to the second database, that’s all there is at the moment…just that one table with a ton of rows in it. Each row takes maybe 100 bytes, and with an average of around 30 rows a day per a location you end up with a database that is about 1Mb after a year’s time (per location). Not bad at all for the amount of data being saved. Searching it is pretty quick too…my database at the moment has about 11,000 rows in it (data for 5 locations back through the beginning of February), and searching through it takes a fraction of a second. In later versions of Seasonality, I might add a way for users to manage this data a bit better. For instance, exporting the data seems like something that user might want to do, and maybe add some AppleScript handling as well. We’ll see where it goes…

Oct 07

Eric Sink, who has written a lot of different articles about starting a small software business, recently wrote one that hit home for me here at Gaucho Software. The article talks about what he learned after a month of starting his own Micro-ISV, or single-developer software company. His situation is a bit different than mine here, simply because he still has his normal paying job and is programming his Winnable Solitaire on the side, but he still makes a lot of good points in the article.

Speaking of Gaucho Software, I recently configured some discussion forums for the company. I believe it will help me keep in touch with my user population, and will help users keep in touch with other users. There are already a couple of discussions up about XRG, so if you are interested check it out.

Sep 14

Well, I just wasted about 5 hours of my life trying to figure out a problem I was having with frameworks, bundles, and my new app. There is a nice way to embed frameworks into an application, as shown in an excellent video tutorial by Jonathan “Wolf” Rentzsch. The problem comes when embedding a framework into a plug-in bundle. I went through the tutorial, except embedding the framework code into my bundle. Things compiled fine, but when I went to run my app, it choked and complained that it could not find a method in a class within the framework.

Unfortunately the debugger was kind of flaking out on me…it was stepping at blank lines without any code and returning out of functions early. This led me to believe that maybe the debugger wasn’t looking at the right code. I couldn’t for the life of me figure out what was going on though. I tried doing a clean build of everything, making sure the frameworks were being included in the bundle, and that the bundle was in the Plugins directory of the app. Everything checked out fine. So if the structure was set up fine, why wasn’t the correct code being executed? I ended up finding the problem was two-fold.

First, I had an old version of the framework I was trying to embed in my ~/Library/Frameworks directory. The old version contained the class I was trying to use, but the class didn’t have the method I was calling yet. I removed that file, and tried running the app again only to find that it couldn’t find the Framework it was looking for. Aha! That explains why the debugger was acting funky….but why isn’t it finding the framework that is included in the bundle?

After poking around a bit more, I came to the point where I set the installation path to “@executable_path/../Frameworks”. Apparently, when embedding a bundle, the @executable_path is set to the application path and not the bundle path. I suppose this makes sense, after all the bundle isn’t the primary executable…it’s just a dynamically loaded library. However, there is no linker definition for @bundle_path or something similar, so unless the bundle is always at a hard-coded path, there is no way to embed a framework into a bundle.

The work-around I ended up doing was just to embed all the frameworks I need directly into the application. This bothers me though, because I know some of the frameworks will only be used in a single bundle, so it doesn’t make sense for them to be embedded in the app and not the bundle.

Anyway, I’m posting this here in the hopes that I can save someone else hours of confusion. :-) If anyone knows of another way to embed frameworks into a bundle without hard-coded paths, send me an email.

Feb 19

For awhile now, people have been requesting that I put something in XRG’s interface to allow them to turn off the UI Elements, such as having the XRG icon shown in the dock. There has always been kind of a hack to do this, by adding the following text to the app Contents/Info.plist file:

<key>NSUIElement</key>
<true/>

This is fine, but in Panther it got a little bit more difficult. Panther now caches these Info.plist files. This is great…the more caching the better, especially for things like Info.plist files that don’t change often. The bad thing is that the cache doesn’t check the last modified date of the plist file. Instead, it checks if the modification date for the .app directory has been changed. I’m not sure why they would do this, as it seems to me that checking the plist file modification date would be just as easy, and that way they know they have a copy of the latest file.

Some people have remarked here that if you move the application to a different directory and back, that the cache gets updated and all is well. This is fine, if a user is changing this value by hand and using the Finder to do it, but it leaves a little to be desired if you are trying to change this value programmatically. I thought of just moving the .app to “X Resource Graph 1.app” and then back real quick, but that doesn’t seem like a nice way of doing things. So that got me thinking, and I found a much easier way to do it using the simple Unix executable, “touch”. I was very pleased to find that making the change manually and touching the application worked just fine. Since it’s very easy to run a quick system command from code, this shouldn’t be a problem at all, so it should be in the next version of XRG.

Anyway, so if anyone is trying to do this same thing from code, hopefully this will help. Now all I need to do is find a way for the change to take effect without having to restart the app. Maybe some kind of hack on the Dock like the one other coders use to add rogue menu extras.

Jan 29

Brent Simmons, the author of NetNewsWire has set up a Yahoo Groups mailing list for people interested in setting up their own Mac software company. Since I’m very interested in starting my own shareware company, I signed up for the list. Hopefully the list will generate a strong community of smaller software developers.

Along the same lines, Slashdot posted an article today on the same topic, but not specific to the Mac platform.

Jan 08

MacShareware.net today released an SDK to help save Mac software developers time when releasing their applications. If you have released a piece of software before, you know it is a ton of work. I usually spend a couple of hours writing something up, and posting it to all kinds of web sites. With MacPAD, it will be a lot easier. From their site, it sounds like Windows developers already have something similar to this…

Basically, how it works is you create a PAD file with information about your application release. This has a short description, long description, release notes, etc, all contained in an XML file. You then upload this file to your website and let other websites such as VersionTracker and MacUpdate know where your PAD file is. Then, all you have to do to release a new version is to simply update the PAD file at that URL. Other servers should pick up the change in a matter of hours.

I really hope that other software sites adopt this method of updating software, as it would make my life a lot easier when releasing XRG. The project is open source and has a page on SourceForge. You can find out more information about the MacPAD SDK here.

Dec 16

Jonathan Rentzsch has an interesting blog posting listing the top 10 things he loves about Objective C and the top 15 things that he hates about Objective C. If you are at all interested in Objective C, check it out.

I would have to say that categories is my favorite Objective C feature. In case you don’t know, categories allow you to add methods to a class definition without changing the original class. This means that you can add functionality to classes that you don’t even have the code for. In the past, to accomplish something like this, I would create a subclass of the original and add my method there. Categories are much more useful because any object of the type that is being categorized automatically obtains the new functionality without any changes in code.

Nov 13

For me, coding at work and coding at home have always been different. When I started my job at Ephibian, I learned a lot about web and database programming, but at home, my personal site never really improved, or changed much at all. My take on it is that when I get home from work, I don’t really feel like doing anything involving web programming or database programming because I’ve been doing that all day.

I’m reminded of something an old friend said back when I knew him in high school. He was very bright when it came to anything having to do with computers. I asked him what profession he was planning on getting into after graduation, and he said he was interested in becoming a doctor. I asked him why not do something like CS, and he claimed that computers were for fun and enjoyment…he didn’t want to ever have computer related stuff turn into work. At the time, I thought he was kind of crazy, now I understand what he meant by that comment.

Now, I’m not saying that I don’t enjoy programming. Quite the contrary actually…I love to program in my spare time even though I do it all day at work. But recently I’ve been considering finding a job doing Macintosh-related development after my wife, Katrina, and I move next year. Ever since starting XRG development, I’ve really enjoyed developing for the Mac platform. Objective C is a nice language and Cocoa makes things easy to do. However, I don’t want to give up my hobby of developing Mac freeware/shareware, and I’m concerned if I get a job developing at a Mac software company, I will no longer have the desire to continue developing personal projects such as XRG.

For other developers out there, what do you think? Are there types of coding that you love doing so much that even though you code at work, you still have no problem coming home and coding something in a similar language or for a similar platform?