Showing posts with label apple. Show all posts
Showing posts with label apple. Show all posts
Thursday, June 09, 2011
Why Apple is charging you to store non-iTunes music in iCloud
If you own some music that you bought from iTunes and you choose to "upload" it into iCloud, you're not really uploading anything. Apple already has it. You originally bought it from them. They just have to store the fact that you are allowed to access their copy of the song. Six million people can "store" Poker Face in iCloud, Apple has to keep only the one copy. Us nerds call this single-instance storage.
On the other hand, if you ripped some music from a CD that you own, and you want to upload that into iCloud, Apple has to actually accept the song from you and allocate disk space to store it. That costs them money, and everyone knows that Apple doesn't do anything for free, so you can bet they're going to charge that cost back to you.
Friday, May 14, 2010
Adobe is becoming the Jay Leno of developer tools
Adobe needs to take a page from David Letterman: "You get fired, you get another gig! You go across the street and you punish them and you make them eat your words!"
Adobe is trying to leverage public opinion - and even government intervention! - by portraying itself as the victim of a monopoly power. They start with the assumption that the iPhone is the only gateway to the mobile web, and of course it's not. The high road would be to make a Flash runtime for Android that kicks so much ass that Apple has to change their stance or be left behind in the market. This duplicitous war of words is a low road, a beggar's stance. A Jay Leno move.
Friday, April 23, 2010
Snow Leopard, external displays, and fonts
UPDATE 05/03/2010: The correct answer seems to be this one: 10.6: Re-enable LCD font smoothing for some monitors. "The problem with the Automatic option is that OS X incorrectly detects many third party LCD monitors as CRTs, and consequently, disables LCD font smoothing."
A couple months ago I purchased a new 13" Macbook Pro. This was before the April updates, so it's the mid-2009 model. As an external display I'm still using the BenQ FP202W that I've had since 2006. The MBP connects to the BenQ with an official Apple-branded MiniDisplay-to-DVI adapter.
I've boiled the weirdness down to a reproducible case:
(1) Open XCode. The editor screen looks like this:

i.e. it looks normal. Legible.
(2) Connect the adapter to the BenQ monitor and connect the adapter to the MiniDisplay port on the laptop. My desktop appears on the BenQ and XCode still looks normal.
(3) Quit XCode and restart it. Now the editor looks like this:

It's the same font (Monaco Regular 12) but the rendering is somehow different. Weak and spidery. The difference is noticeable in the screengrabs, in person the difference is even more jarring.
TextMate does the same thing. I have TextMate also using Monaco Regular 12, so maybe it's related to the font? I have no idea what's causing this or how to fix it.
Wednesday, January 20, 2010
The Nerd in the High Castle
I like to read history books, and that includes the history of the computer industry. Steven Levy's stuff is pretty good, even if sometimes he gets a little breathless in the telling. Dealers of Lightning, West of Eden, Soul of a New Machine, stuff like that.
From reading enough of these, and from the tech press as well, I know there's this notion floating around that during the early 80s Apple was fighting the wrong enemy. (Pirates of Silicon Valley also plays this note.) During that era, Apple focused on IBM instead of on Microsoft. But Microsoft and MS-DOS really won their independence from IBM during the Clone Wars. Everyone wanted to clone the IBM PC, and run MS-DOS on it, because IBM had been so successful. If Apple had somehow won market dominance over IBM in the early 80s, they would have also defeated Microsoft by proxy.
That got me thinking though, that Microsoft probably would not have stayed out of the OS market. They were still a successful applications company at the time and, if PC-DOS had failed, they surely would have made another attempt at an OS product. Now it starts to sound like the plot of a alternate history novel, doesn't it? On the back cover: "What if Apple had defeated IBM in 1984? What if Microsoft had partnered with Commodore to sell MS-Windows in 1986?"
Wow I just realized... if someone wrote that book, I would totally read it.
Wednesday, October 14, 2009
Can I make a UIView transition to itself?
Sure, why not?
Let's say you have a UIViewController and you want the base view to do a CATransition from itself to itself:
- (void)doTransToSelf {
CATransition *anime = [CATransition animation];
anime.type = kCATransitionPush;
anime.subtype = kCATransitionFromRight;
anime.duration = 0.5;
UIView *mySuper = self.view.superview;
[self.view removeFromSuperview];
[mySuper addSubview:self.view];
[mySuper.layer addAnimation:anime forKey:nil];
}
CATransition *anime = [CATransition animation];
anime.type = kCATransitionPush;
anime.subtype = kCATransitionFromRight;
anime.duration = 0.5;
UIView *mySuper = self.view.superview;
[self.view removeFromSuperview];
[mySuper addSubview:self.view];
[mySuper.layer addAnimation:anime forKey:nil];
}
Or, changing this to work on a subview of self.view is trivial.
So, why would you want to do this? In my case, I have a collection of data objects and a UIView that is the user interface for editing one object. When the user is ready to move on and edit the next object in the collection, the user interface doesn't substantially change, I'm really just changing the data object that is the target of the user's edits. So I want to re-use the same view with the same set of IBOutlets, and just do the transition as a visual cue to the user - "okay, you're working on a different object now."
Sunday, June 28, 2009
Why won't my backBarButtonItem use its action?
Or, How to make a backBarButtonItem send its action to its target.
Answer: you don't.
Because a backBarButtonItem is a UIBarButtonItem, it has "target" and "action" properties, leading you to believe that if you assign values to those properties, shit will happen. Alas, shit will not happen. Or rather, the usual shit will happen, but not the extra shit you hoped would happen. The backBarButtonItem is special - no matter what you do with those properties, «target» will never receive a message for «action».
What you can do instead is assign a delegate to either your UINavigationController or UINavigationBar. Both of these classes have delegate protocols that give you opportunities to act when the stack of view controllers changes. I've been using my root view controller as the delegate object, since that one never gets popped off the stack.
Wednesday, April 15, 2009
Putting a background behind a UIView transition
When doing a setAnimationTransition: with a UIView, you can do a "flip left/right" or a "curl up/down". If you do a flip left/right, you'll usually see a blank black screen "behind" the view as it flips. (The built-in Stocks app does this.) Recently someone asked me if you could have something else back there, and I thought "huh, that's interesting, I never tried that" and we investigated. It turns out that you can, but you have to set up the view stack properly.
So let's say we have 3 UIView objects, frontView, backView, and rootView. Before the transition begins, frontView is a visible subview of rootView and backView is not yet in the view stack. You begin an animation block and then (usually) do [frontView removeFromSuperview] followed by [rootView addSubview:backView], then commit the animation block and watch the animation take place. You might think that adding another subview of rootView, one that sits below frontView, would make that view be visible behind the animation during the transition. At least, that's what I thought, but it doesn't work. I'm not sure why, but it seems that rootView and all of his subviews become "invisible" during the transition.
But, but! if you put another UIView under rootView, that view will be visible during the transition. Maybe in your project, your views are already set up that way. But if frontView and backView are immediate subviews of the main window, then of course nothing can be below the main window, and you'll need to interpose another UIView object into your view stack.
Instead of posting sample code, I'm going to suggest downloading the LocateMe sample app from ADC. It's already designed with a "main" view and a "flipside" view who are subviews of a root view, and the root view is a subview of the main window. Get the project, open the MainWindow.xib, and add a UIImageView (for example) in the main window:

Make sure the toggleView method is using UIViewAnimationTransitionFlipFromLeft(Right) in its animation block (it doesn't make sense with the curl up/down animation) and then build and run the project.
Friday, January 09, 2009
iPhone: Development provisioning profiles and the Entitlements file
I found what appears to be a disconnect between Apple's provisioning documentation and what actually goes on in Xcode. If you want to build your project for development (testing) on your own device, the documentation says to select the top-level build target of your application, open the Info window, click the Build tab, and set "Code Signing Identity" -> "Any iPhone OS" to be "iPhone Developer: YourFirstName YourLastName". (Presumably you must enter your name exactly as it appears on the Team page of your developer portal.) That part works fine. Next, according to the documentation, you should set "Code Signing Provisioning Profile" to be the provisioning profile you created for your combination of name/device/application. When I go to my XCode, there is no such entry!
Instead, just above "Code Signing Identity" is an entry called "Code Signing Entitlements". What I had to do is create a new property list file in my project called Entitlements.plist. The contents of that file look like this:

Where the application-identifier is the exact App ID from your developer portal, including the 10-character prefix. And then back in the Info window, set the value of "Code Signing Entitlements" to simply be "Entitlements.plist". Drag and drop the provisioning profile onto the XCode Organizer, if you haven't already. Now you can build and push the app to your iPhone.
Monday, January 05, 2009
Two Desktop icons in Open File sidebar
I recently had a problem similar to this one:
Fix multiple ghost aliases in the Finder's sidebar
I had two Desktop icons in the sidebar of my Open File dialog boxes, in all of my applications. I had only one Desktop icon in the sidebar of my Finder, though. The advice on that page is good advice, but you don't have to trash the sidebarlists.plist file. Instead you can edit it with the Property List Editor, and under "useritems" you'll find the duplicate entries that are giving you grief. Delete one of them, save it, and then - this is key - logout and log back in.

Wednesday, December 24, 2008
Dear MBW: I just want things to be like they used to
I used to love MacBreak Weekly. But I finally gave up and unsubscribed. Why? Here's an example. And keep in mind, this is not an isolated incident. This is a representative sample:
Episode #117. They've got Wil Shipley. Great guest. Should be a great show. Wil is (trying to) talk about scanning barcodes with a cellphone camera. Andy Ihnatko interrupts with a digression about how he takes pictures of books in the store and later buys them online. Leo LaPorte interrupts Andy with a digression about how buying books online is just so much more convenient. Andy interrupts Leo with a digression about how he's finding more and more books scanned into Google. Alex jumps in to defend the value of the printed book. The whole thing devolves into a discussion about which books are worth owning in physical form. (Answer: books with lots of pictures.) Total time before Wil even speaks again: six minutes. And he never did return to exactly the point he was trying to make before he was interrupted. It was just lost.
So okay, six minutes out of a 90 minute show, no big deal, right? Couple points. One, the thread of the meaningful conversation was destroyed by the interruption. Two, it happened again. Wil started to talk about using your mobile device for comparing prices, and the group launched into another digression about some camera store down the street that overcharges for everything. Elapsed time between the end of the first interruption and the start of the second: Forty-five seconds.
The conversations used to be more coherent. The digressions were fewer, and more interesting when they did happen. Remember the Rat Hole music? They don't even bother to play it anymore, because if they did, it would run non-stop.
It's not too late to right the ship, MBW. I miss the show you used to be.
Wednesday, September 24, 2008
In case you missed it in the 80s, here comes the sequel
App Store: I'm out (Fraser Speirs)
Apple Extends NDA to Rejection Letters (Arnold Kim)
Beneath Apple (Brent Simmons)
"[Microsoft] is annoying, but (in the end) not half so annoying as watching Apple inscrutably and relentlessly destroy itself."
- Neal Stephenson in 1999
Thursday, August 14, 2008
We all suspected it, and now it's confirmed
I'll give you a little hint here: some of us, back when I was inside the fruity compound, occasionally held contests to see who could get the weirdest, most funky and outrageous, rumors posted to one of the major rumor sites.
- Chuqui 3.0
Sunday, May 25, 2008
Safari bookmarks and Sync Services
For my own purposes, I need to make a Cocoa program that knows about my bookmarks in Safari. Lucky for me, Safari submits its bookmarks to Sync Services, according to Syncrospector:

To complete my evil plan, I also need to know the last time I clicked on a bookmark. Lucky for me, the sync schema includes a "last visited date", according to /Applications/Safari.app/Contents/SafariSyncClient.app/ Contents/Resources/SafariClientDescription.plist:
<key>Entities</key>
<dict>
<key>com.apple.bookmarks.Bookmark</key>
<array>
<string>url</string>
<string>last visited date</string>
<string>name</string>
<string>position</string>
<string>notes</string>
<string>parent</string>
<string>com.apple.syncservices.RecordEntityName</string>
</array>
So I just need to write my own Sync Services client that syncs with the com.apple.bookmarks.Bookmark(s)...
Uh oh. Let's have another look at that Syncrospector screenshot. The displayed entity there is a Bookmark, but it doesn't appear to have a "last visited date" property. Neither do any of the others.
I went ahead and made my own Sync Services client, so I could poke around in there for myself, but it sure seems to be that Safari doesn't set that property on the bookmarks that it submits to the truth database (it's not required to) even though Apple's own sync schema defines such a property.
Bah. Back to the drawing board for me.
Thursday, May 22, 2008
OS X, Bonjour, Apache
As part of some experimenting the other day, I went into System Prefs on my laptop running 10.5 and activated Web Sharing. To my surprise, my personal web site did not appear in Safari's Bonjour list, nor did any HTTP service appear in Bonjour Browser. I could reach the web page if I typed in the URL, it just wasn't being advertised by Bonjour. I had a very clear memory that it used to work with Bonjour, so I started asking why it's not working now. I did some Googling, I searched Apple's support forums, I finally got my friend Thomas involved. He, also, remembered that it used to work with Bonjour, he, also, could not find any leads via Google. (And he's a really good Googler.) He suggested that we check the httpd.conf on my laptop. ("Mac use conf file? That's unpossible!") Sure enough, here's what we found:
<IfModule mod_bonjour.c>
# Only the pages of users who have edited their
# default home pages will be advertised on Bonjour.
RegisterUserSite customized-users
#RegisterUserSite all-users
# Bonjour advertising for the primary site is off by default.
#RegisterDefaultSite
</IfModule>
I made a trivial edit to Sites/index.html in my homedir, toggled Web Sharing off and on one more time, and presto! there was my personal site listed in Safari's Bonjour list.
I'm not sure if this is something new in Leopard, or if it changed in Tiger and I just never noticed. I'm sure Panther didn't work this way. And I'm not saying the Leopard way is bad. It just surprised me.
Friday, April 25, 2008
How many angels can dance on the tip of a mouse pointer? I don't care.
I used to care about piddly shit like this. The day I quit caring was the day I started wanting a Mac. (That day, incidentally, was about two years before I actually got a Mac, so don't give me any crap about rationalizing in Apple's defense.) After five years of having a Mac, I still don't care and I feel great! It's like switching from Catholic to Buddhist.
That's what not having autofocus is like to people who've been using it for the past 10 to 30 years (in my case, 20 years). BLONK! BLONK! BLONK! I'm serious. It's that bad. Not exaggerating even a tiny bit.
Bull. You're exaggerating quite a bit, because the software isn't behaving inside your narrow definition of "correctness."
(If you skip down past the hyperbole to the part where he actually starts programming, there is some interesting stuff.)
Saturday, March 15, 2008
Creating a menu-based SIMBL plugin
There are a hundred tutorials on creating nib-based Cocoa applications. And there's at least one good write-up on how to make a Cocoa bundle that can be loaded by SIMBL. SIMBL has taken on increased importance with the release of Leopard, because InputManagers can no longer be installed in user folders. They must be installed at the system level in /Library/InputManagers. However, if you or your admin install just SIMBL at the system level, SIMBL acts as a fine-grained meta-manager, loading SIMBL-compatible plugins on a per-user and per-application basis.
Normally Cocoa bundles don't include nibs, but you can add them. The CULater wiki doesn't go so far as to guide you thru adding a nib to your Cocoa bundle, or how to attach the nib-generated menus to your target application. Since we can't edit the nibs of the target application, we have to install our nib contents programatically using Objective-C.
So that's what we're going to do today. I'm going to assume you already have SIMBL installed on your computer, and that you are at least novice-level with XCode and Cocoa. I specifically cover the differences between Interface Builder 2 and Interface Builder 3, mainly to point out how much IB3 has been improved.
1) Open XCode and start a new Cocoa Bundle. Let's call it "George".
2) Before we create any classes, we'll use Interface Builder to make the menu. The menu is going to have a single "About..." menu entry. A little later when we load the bundle, we'll insert our menu into the menubar programatically, since we can't edit the nib file of the target application.
When you create a Cocoa application in XCode, XCode automatically creates your first nib file in your project for you. But since we created a bundle, our project doesnt have any nibs yet.
2a) In XCode 3, go to File->New File and make a new Cocoa nib file. Be sure to create an "empty nib" file not an "application nib" file. Just call it "Menu.nib". Doubleclick the nib file in XCode to open it in Interface Builder.
2b) In XCode 2, you can't create an empty nib from within XCode. Open Interface Builder directly, and choose an empty Cocoa nib as your starting point.

After building the menu (step 3 below) save your new nib file in your project directory as "Menu.nib". It will ask you if it should add the nib to the project, and if it should add the nib to the target "George". Answer yes to both.
3) Drag an NSMenu from the IB palette to the IB main window (the window that contains "File's Owner" and "First Responder".) Then (XCode 3 only) doubleclick it to create an editable menu on your screen. Delete all but one menu item, and rename that one to "About..." Save your work then switch back to XCode.
4) Time to create the class which will contain our menu callback and, in this case, also bootstrap our plugin. Create a new Objective-C class file called "GeorgeController". Be sure to also create the header file. Since we're going to add the menu programatically, we need to create a variable that will be our handle on the menu. That goes in GeorgeController.h:
@interface GeorgeController : NSObject {
IBOutlet NSMenu* topMenu;
}
@end
IBOutlet NSMenu* topMenu;
}
@end
Now in GeorgeController.m, add a typical dealloc method, and an almost typical init method:
#import "GeorgeController.h"
@implementation GeorgeController
- (id) init {
self = [super init];
if (! self)
return nil;
[NSBundle loadNibNamed: @"Menu.nib" owner: self];
return self;
}
- (void) dealloc {
[super dealloc];
}
@end
@implementation GeorgeController
- (id) init {
self = [super init];
if (! self)
return nil;
[NSBundle loadNibNamed: @"Menu.nib" owner: self];
return self;
}
- (void) dealloc {
[super dealloc];
}
@end
In the init method, we're loading the nib file we just created.
One more thing before we switch back to Interface Builder - let's write the callback that we're going to attach to the "About..." item:
- (IBAction) orderFrontAboutPanel: (id) sender {
NSImage* icon = [[NSWorkspace sharedWorkspace] iconForFileType: @"bundle"];
[icon setSize: NSMakeSize(128, 128)];
NSDictionary* options;
options = [NSDictionary dictionaryWithObjectsAndKeys:
@"George", @"ApplicationName",
icon, @"ApplicationIcon",
@"0.01", @"Version",
@"", @"ApplicationVersion",
@"Copyright (c) 2008 __MyCompanyName__", @"Copyright",
nil];
[NSApp orderFrontStandardAboutPanelWithOptions: options];
}
NSImage* icon = [[NSWorkspace sharedWorkspace] iconForFileType: @"bundle"];
[icon setSize: NSMakeSize(128, 128)];
NSDictionary* options;
options = [NSDictionary dictionaryWithObjectsAndKeys:
@"George", @"ApplicationName",
icon, @"ApplicationIcon",
@"0.01", @"Version",
@"", @"ApplicationVersion",
@"Copyright (c) 2008 __MyCompanyName__", @"Copyright",
nil];
[NSApp orderFrontStandardAboutPanelWithOptions: options];
}
and add the method signature to the .h file:
@interface GeorgeController : NSObject {
IBOutlet NSMenu* topMenu;
}
- (IBAction) orderFrontAboutPanel: (id) sender;
@end
IBOutlet NSMenu* topMenu;
}
- (IBAction) orderFrontAboutPanel: (id) sender;
@end
Make sure to save both files so IB can see your changes.
One thing to note here is that our plugin can access the NSApp instance of our target application - here we call on NSApp to create an About popup window. A little further down we'll use NSApp to get at the application's menubar. Your plugin will probably call methods of NSApplication to initiate most of its interactions with the target app.
5a) Now go back to Interface Builder. If you're using IB3, click on "File's Owner", then open the Inspector and go to the Identity pane. Under "Class Identity" select GeorgeController. If GeorgeController is not listed, you may need to go to File->Read Class Files... and navigate to GeorgeController.h in your project, then try again.
Now that IB knows that GeorgeController is the File's Owner, you should be able to choose Connections from the Inspector and see topMenu under Outlets and orderFrontAboutPanel: under Received Actions. Drag from topMenu to the titlebar of your IB menu under development, and then drag from orderFrontAboutPanel: to the About... menu item.

Here's a gotcha: if your header file contains syntax errors, IB won't be able to parse it but also won't tell you that it can't. Like a naughty puppy, it will just quietly not do what you want it to do. If IB seems to be defying you, try compiling your project and see if you have any syntax errors.
5b) If you have Interface Builder 2, click on "File's Owner" and then choose Custom Class from the Inspector. If GeorgeController is not listed as an option, you need to actually drag GeorgeController.h from XCode's main window to IB's main window. Set GeorgeController as the custom class for File's Owner. Now choose Connections from the Inspector, then Ctrl-drag from File's Owner to the titlebar of your IB menu under development, then click Connect in the Inspector.
Next Ctrl-drag from the About... menu item to the File's Owner object. If the Inspector says "No actions in GeorgeController", click on the Classes tab in the IB main window, then select "Read GeorgeController.h" from the Classes menu in the menubar, then try the Ctrl-drag again. When you see orderFrontAboutPanel: in the Inspector, hit Connect. XCode 3 may be looking pretty attractive by now. :)

6) Next we're going to use the awakeFromNib method as our opportunity to attach our menu to the target application's menubar. You don't call awakeFromNib from your code - when a nib is loaded, awakeFromNib is automatically called on the instance of the class associated with File's Owner. So define an awakeFromNib like this:
- (void) awakeFromNib {
NSMenuItem* item;
item = [[NSMenuItem alloc] init];
[item setSubmenu: topMenu];
[topMenu setTitle: @"George"];
[[NSApp mainMenu] addItem: item];
[item release];
}
NSMenuItem* item;
item = [[NSMenuItem alloc] init];
[item setSubmenu: topMenu];
[topMenu setTitle: @"George"];
[[NSApp mainMenu] addItem: item];
[item release];
}
Note that we finally use the IBOutlet topMenu, this one moment is the whole purpose of his existence. Also, we take advantage of NSApp again to give us the mainMenu of the target application so we can manipulate it.
7) Now we're ready to do the work specific to SIMBL. Our class needs to define a class method - not an instance method! - called load which takes no arguments and returns void. SIMBL always looks for a load method in the NSPrincipalClass (we'll get to that) and that's where we bootstrap our plugin. In our case, there's not much to do.
+ (void) load {
[[self alloc] init];
}
[[self alloc] init];
}
When inside a class method, "self" does not represent an instance, it represents the class itself. So we alloc and init a new controller instance, our init calls loadNibNamed:, which causes awakeFromNib to be called, which causes our menu to be attached to the menubar, which worries the cat that killed the rat that ate the grain that sat in the house that Jack built.
8) Finally, we edit the Info.plist. Before it calls our load method, SIMBL looks in the Info.plist of our bundle to see (a) which application(s) we want to plug into and (2) which class in our bundle contains the load method that we want SIMBL to call. In this example our bundle has only one class, but in a real project you'll have more.
This next part is straight from the CULater wiki.
If you just doubleclick the Info.plist in XCode, it opens in the XCode editor. If you'd rather, you can rightclick and Open With Finder, which will bring up the Property List Editor. Either way, set the NSPrincipalClass to "GeorgeController", and then create a new array key called SIMBLTargetApplications. Since this is an array, you can create multiple entries and have your plugin be loaded into multiple applications. In our example, we're just going to have one array entry, telling SIMBL that George should be loaded into Apple Mail:
<key>NSPrincipalClass</key>
<string>GeorgeController</string>
<key>SIMBLTargetApplications</key>
<array>
<dict>
<key>BundleIdentifier</key>
<string>com.apple.mail</string>
<key>MaxBundleVersion</key>
<string>*</string>
<key>MinBundleVersion</key>
<string>*</string>
</dict>
</array>
<string>GeorgeController</string>
<key>SIMBLTargetApplications</key>
<array>
<dict>
<key>BundleIdentifier</key>
<string>com.apple.mail</string>
<key>MaxBundleVersion</key>
<string>*</string>
<key>MinBundleVersion</key>
<string>*</string>
</dict>
</array>
How to know the BundleIdentifier and BundleVersion? Don't try to guess at it, cause they're not necessarily related to the application's name or displayed version. You need to manually inspect the application's own Info.plist. Go to the application in the Finder, right-click, and choose "Show Packge Contents". Go into the Contents folder and open the Info.plist that you find there. Look for the CFBundleIdentifier (not CFBundleName!) and CFBundleVersion (not CFBundleShortVersionString!) Although, SIMBL will allow you to use wildcards in the versions as you can see in our example.
9) You're ready to build. Hit Build and deal with any errors. If you've followed the example code exactly it shouldn't generate any warnings either. Right-click the George.bundle in the XCode main window, select Reveal in Finder, and drag the bundle to your ~/Library/Application Support/SIMBL/Plugins directory. Start your target application (Apple Mail if you followed the example Info.plist) and you should see a "George" submenu in the menubar. Congratulations! You're ready to build out our example into a plugin that actually does, you know, stuff.
Credits:
Mike Solomon for the Cocoa Reverse Engineering page on the CULater wiki.
I figured out most of what wasn't in the wiki by picking apart the source code to GreaseKit. GreaseKit is Copyright (c) 2007 KATO Kazuyoshi.
Saturday, March 08, 2008
Dear Mac developers: the mobile app market existed before you came along
One of my friends sent me this excellent article examining the state of the mobile app industry. People who want to bitch about the iPhone app model should read some history first. Then at least they can do some informed bitching.
Mobile Applications, RIP
Wednesday, February 13, 2008
Wishlist: more efficient scrolling for the iPhone
I've had an iPod Touch for about a month now, and I love it to death. But as humans tend to do, I'm going to be general in my praise and detailed in my gripes. But wait! because I have a proposed solution to my gripe.
My praise: it's awesome. It's still not my perfect iTablet, but I'm using it for the same reasons - I can access the net, in comfort, without using a keyboard.
My gripe: there is no way to jump to the bottom of a web page in Mobile Safari, or to quickly scroll through a very vertical page. This recently got especially tedious for me while I was skimming some archives of Daring Fireball, because some of his essays are rather long, and the link to the next article is always at the bottom. Flick, flick, flick, flick, flick, flick, to get to the bottom of the page. Link to next page, repeat.
Now when you put your finger on a page and start to drag it, a translucent scrollbar appears in the margin to give you a sense of where you are in the page. But you can't grab that scrollbar and use it for anything. It's more of a "scroll indicator."
So my proposed solution: why not let me grab it? If I put one finger on the page, the scrollbar appears, and then I can "pin it" under another finger (probably a finger of the opposite hand) and as long as I have it pinned, moving my finger to the bottom of the screen takes me to the absolute bottom of the web page, and the top of the screen, vice versa. The rate of the scrolling would be relative to the size of the page, just like a windowed app on a desktop computer. I'll be the first to say this isn't intuitive or even convenient - it's actually a little awkward. But dammit, it would work and it would be there for people who know about it.
My other gripe: there's no "Find in Page" with Mobile Safari. What's up with that? For about the first week I kept going to the magnifying glass when I wanted to find a word on the page. Even though I knew that button brings up Google, my brain kept trying to map my ⌘-F reflex to something. I don't have a solution for that, except - add it!
Monday, January 28, 2008
Macbook Thin == iTablet beta
Well, we didn't get an iTablet, we got Macbook Mini. Except it's more like a "Macbook Thin." Which is interesting because making it Thin instead of Mini addresses Bill Manning's complaints about UMPCs, which I thought were spot-on.
I wasn't predicting a tablet, just hoping for one. The Macbook Thin is a great product for the "not me" demographic. There's a lot of neat tech packed into the thing but I don't have a need or a desire for one. I will stand by one thing I said, which is that there's a lot of overlap in the components that go into the Thin and the components that would go into an iTablet. Imagine breaking off the screen half of the Thin, replacing the keyboard with a 13 inch touchscreen, and you'd have a pretty kickass tablet. The internals of the two products would be pretty similar.
Right before Macworld there was a rumor that a tablet is in development, but wasn't going to be ready by January. (This rumor persists, and is gathering strength.) What if the Macbook Thin was actually a "Plan B" product, when it became clear that the tablet wasn't ready, conceived both to make some money, and also get some of this superthin tech out into the field and shake out the bugs?
One thing that is scary about the Thin, relative to my tablet obsession, is the price. If the high-end Thin is $3000, how much might the tablet cost? $4000? $5000? That's too much to pay for a device which is by design an ancillary device to another computer you already own. Maybe that in itself was the reason for delaying the tablet - getting the Thin into production will also allow them to ramp up production of components, streamline the production lines, and bring down costs, so that the eventual tablet will hit a reasonable price point.
Tuesday, December 04, 2007
Here's hoping against the "Macbook Mini"
"As Macworld approaches, reports of an ultraportable MacBook are following patterns of previously expected products that eventually materialized," analyst Gene Munster wrote in a note to clients. "We believe these reports are legitimate and continue to expect Apple to introduce a MacBook with a significantly smaller form factor."
- Piper Jaffray analyst Gene Munster
One might assume that Piper Jaffray has an "inside source" at Apple. And maybe they do. But another thing that these analysts do is watch the supply chains. The individual components of a new computer product have to be ordered months in advance, so by watching who is buying what in what quantities, predictions can be made.
If you consider the individual components that might go into a "Macbook Mini" or might go into an "iTablet", there's actually a fair amount of overlap. So here's to hoping they've read the tea leaves wrong, and we get something less "Macbook Mini" and more "iTablet".
Why?
For starters, the UMPC market already has several offerings, and even though they are neat little devices, I don't see a lot of people ditching their traditional laptops for one. So if you were jonesing for such a device, they're here now, but it's a niche market. It's not stealing global marketshare from traditional laptops. Since OS X is already considered a niche market itself, a UMPC running OS X would be targeting a niche of a niche. If you're a one-man startup, "niche of a niche" smells like opportunity, but if you're already a multi-billion-dollar company, it smells like a poor return.
What's more, I think Bill Manning is on target when he says that UMPCs have "a cool factor of 10" but ultimately they aren't practical. He's touting the Macbook as his laptop of choice, but his criticisms of UMPCs apply in general.
An Apple UMPC just wouldn't be much to shout about.
A true tablet computer, on the other hand... that's my wish. At the end of my work day I want to get away from my office and away from my keyboard, but darn it, I'm a nerd and I still have leisure activities that involve a computer. I'd like to kick back in my recliner and read some mail or read some Apple ][ History or play a web game, and do it reclined and do it without pounding keyboard.
An iTablet would address all of Bill Manning's gripes about UMPCs. It would have a larger screen, but still be small and light, because you omit the keyboard half of the computer. It won't mess with your muscle memory of your work keyboard, because there is no keyboard. It could have the virtual keyboard, or handwriting recognition via Inkwell, or hey why not both? At this point both types of software are completed products.
My perfect iTablet would have flash-based storage only, and would treat CPU power as secondary to cooling and battery life. The perfect iTablet must run quiet and cool, because who can really keep their laptop in their lap anymore, much less hold it in their hands.
Now imagine this: if you own an iTablet, and you also own a Mac, it gets better. The iTablet itself has a cool, low power CPU. But the computational power of your iTablet actually goes UP when it can contact your Mac, without running any hotter. How is such magic possible? Oh dear, everyone has forgotten XGrid.
Subscribe to:
Posts (Atom)