Monday, April 15, 2013

CanoScan LiDE 200 on Mountain Lion: Failed to open a Session on the Device because it (the Device) was Locked!

Just a very quick tech note for the Community, since it took me way too long to solve this problem: assuming you have updated your drivers and so on, if your CanoScan LiDE 200 (or similar Canon scanner) still gets you an error in Image Capture on a Mac, the scanner might be locked.

The lock switch is on the bottom of the scanner.

I had by then already updated the drivers, but I probably didn’t need to. Unlock; unplug; re-plug; re-launch Image Capture; voila. It took a while to warm up, but then it had been in storage for two years (which is of course why it was locked).

That did the trick for me. Of course it would have been lovely to have the software say “Your Scanner is Locked, Dumbo!” But I guess it’s a more secure lock if you forget it’s there!

Labels:

Wednesday, January 11, 2012

How Third-Party Apps Should Use Siri

Apple’s Siri is a “digital assistant” for iPhone 4S and, presumably, various other products to be released in the future. I expect it will come to the Mac at some point too.

I haven’t used Siri, but I have been following the developments because I think she (in the UK, apparently a he) will become a very big deal once there is an easy way for third-party applications (App Store apps) to take advantage of the voice recognition and natural-language processing Apple runs on its servers.

There has been a lot of discussion online about how this could be done without various apps stepping on each other’s toes. If I say “Siri, remind me at six about Tarkan’s birthday party,” which calendar program will it use for the reminder?

In this case, it will obviously use Apple’s. You could make that configurable but I really doubt Apple would.

I think the answer is as easy as it is obvious, and easier than it is awkward. Apple controls (approves) the name of every app in the App Store. It can easily allow developers to choose a “Siri Name” for an app, also subject to central approval. Keeping these unique should not be hard.

Then you simply tell Siri whom to tell (or ask) what. Much like you did in Applescript, if you had a Mac in the 90’s (or are a total masochist today).

For an app named “Candy Store,” it might go like this:

HUMAN TO SIRI: Siri, ask Candy Store if they have blue gumdrops.
SIRI TO CLOUD: <...sends audio...>
CLOUD TO SIRI: Parsed OK for "Candy Store" : "find 'blue gumdrops'"
SIRI TO APP:   find 'blue gumdrops'
APP TO SIRI:   OK, in stock, $6/dozen.  Options: order, view.
SIRI TO HUMAN: Candy Store has blue gumdrops for six dollars per dozen.
               You can view them or order them if you like.
HUMAN TO SIRI: Order six dozen please.

Siri would of course know the context of that last command, because Siri is tracking a conversation and not just individual commands. You could also be very direct:

HUMAN TO SIRI: Siri, tell Candy Store to cancel next week's shipment.
...
SIRI TO HUMAN: Your Candy Store shipment of four hundred mixed jellybeans
               for Monday, January 16 has been canceled.

If I were Apple I would start this with a very, very simple API, supporting only the simplest directives like “find” and “order” and “do,” but also sending the original text to the app in case the app wants to do its own parsing.

But that’s probably way too utopian of me. Apple will no doubt wait until there is a huge NSDigitalAssistantRequest API and statically-typed conversations and 30% of any digitally-assisted sale going to Cupertino, and start with three hand-picked third-party apps for a year-long trial run before mere mortals are allowed in.

Even then, it could of course be huge.

Labels: , ,

Sunday, November 20, 2011

Meta: old comments published, sorry.

I just realized I had not moderated comments in six million years.

So I did, and published the non-spammy ones. In case there is some kind of notification system and you get an e-mail that your comment from 1932 has been published on this blog: my apologies for the tardiness.

Labels:

UITapGestureRecognizer and “unrecognized selector sent to instance” errors.

This is just a very quick note for search engine posterity, in case anybody has the same frustrating problem I had today.

I am implementing some gestures for an iOS art app (as in a work of media art, the "medium" of which is an iPhone/iPad application). I was following the "Event Handling Guide for iOS" from Apple.

After much Googling and some very informative stops at StackOverflow, I had got basically nowhere. Everything seemed right, my code conformed tightly to the tutorial and to everyone else’s, and everybody else who found a solution had obviously solved a very different core problem than I was facing. What could be wrong?!

It turns out the problem was as simple as:

-(void) handleTap
{
    NSLog(@"*** GOT A TAP ***");
}
    

Now, in real life you would almost never use a method as dumb and simple as that, but when setting up your classes for initial hacking and debugging you just might. According to the tutorial, it should work:

The action methods for handling gestures—and the selector for identifying them—are expected to conform to one of two signatures:
- (void)handleGesture
- (void)handleGesture:(UIGestureRecognizer *)sender

Silly programmer, tricks are for kids! The standard-issue selector looks for only the second signature, and if it doesn’t find it you get the error whenever you tap: unrecognized selector sent to instance! boo!

The solution, then, is to declare and implement the method with the argument. That works fine.

-(void) handleTap: (UIGestureRecognizer *)sender
{
    NSLog(@"*** GOT A TAP ***");
}
    

To be fair, Apple has an enormous amount of documentation available online, and it’s not so shocking that a tutorial is out of date. For us iOS newbies it’s frustrating, but I don’t think anybody else is doing a better job of this at the moment.

Labels: , ,

Friday, October 14, 2011

Rough Draft Epitaph

So many important people have died this year, I thought it best to have at least a rough draft of an epitaph on record in case I need one. I feel fine, but you never know. Ergo:

HERE LIES THE FROST
man under ground.
His hair was long,
his belly round.
He lived quite long
for the risks he took,
but never did manage
to write that book.

Labels: ,

Friday, August 05, 2011

Perl ExtUtils::MakeMaker test overrides (for Makefile.PL).

Nerd post follows; non-nerds, move along.

This took me a while to figure out, and in the end I had to dig around in the source code to figure out just what was going on, so here’s a quick note for posterity since I’m sure somebody else will have exactly this problem at some point. Caveat lector: I’m probably making a bunch of mistakes here. And thanks to brian d foy for showing us how to use test_via_harness.

Basically what it boils down to is this: you are going to have either a bunch of test files in a t directory, or a single test.pl file in the main directory. Or possibly both.

The thing you need to override is different in each case. You might just want to do both in case you change your mind later about the test setup.

Let’s say, for instance, that my special little requirement is that I can get at some shared libraries in the /opt/special/lib directory. The examples below should be understood as code inside your Makefile.PL file. And yes, they are almost identical in this case.

For test.pl override test_via_script.

sub MY::test_via_script {

    my ( $self, $perl, $script ) = @_;

    # Here is some special sauce for the environment:
    my $env_setup = 'LD_LIBRARY_PATH=/opt/special/lib';

    # Here are some Makefile variables that are handled by `make`:
    my $harness_args =
      '"$(TEST_VERBOSE)", "$(INST_LIB)", "$(INST_ARCHLIB)"';

    # Here's the command that will create the target:
    my $command =
      sprintf "\t%s %s -MExtUtils::Command::MM -e 'test_harness(%s)' %s",
      $env_setup,
      $perl,
      $harness_args,
      $script;

    return $command;

}

For t/*.t override test_via_harness.

sub MY::test_via_harness {

    my ( $self, $perl, $tests ) = @_;

    # Here is some special sauce for the environment:
    my $env_setup = 'LD_LIBRARY_PATH=/opt/special/lib';

    # Here are some Makefile variables that are handled by `make`:
    my $harness_args =
      '"$(TEST_VERBOSE)", "$(INST_LIB)", "$(INST_ARCHLIB)"';

    # Here's the command that will create the target:
    my $command =
      sprintf "\t%s %s -MExtUtils::Command::MM -e 'test_harness(%s)' %s",
      $env_setup,
      $perl,
      $harness_args,
      $tests;

    return $command;

}

Etc. & So On

I think it’s a much better practice to keep your test files in t/ anyway, and to always run with the test harness. In fact I usually skip the explicit test harness altogether and run everything with the appropriate prove command (the one that belongs to the Perl I’m using).

However, if you’re dealing with legacy code or not interested in doing real Perl stuff or otherwise just need to “get on with it” then you might well need a test.pl – and remember, test_via_script for that guy!

Here are the obvious links you should follow if you want to know more about this:

And finally, for anyone nerdier than I who is reading this: I know about package MY and I agree it’s probably the better solution, but I think it’s (even more) confusing for novices; and I assume at least some people trying to do this aren’t even Perl programmers.

Labels: , , , ,

Monday, May 02, 2011

Seen Today

  1. A 200HUF cappuccino.
  2. Szamoca vs. Eper.
  3. A mini-skirt! 'Tis the season!
  4. Bright sunlight through green glass socialist balconies.
  5. Prolis, pornósmellü, rövidlábú daughter of the café proprietress.
  6. A one-legged man walking a husky.
  7. Public-service street art sampling both Star Wars and Red Robot.
  8. A giant pink Hello Kitty poster at the optometrist's.
  9. Written on the Bortársaság delivery van, the optimistic take on modern Hungary: “MINDEN RENDBEN A BOR FINOM.”

Labels: