Scripting Bridge question

  • I'm playing around with iTunes and the new scripting bridge in
    Leopard, and I'm having trouble setting the image of an NSImageView to
    the artwork of the current track.

    Using the old NSAppleScript way, this works:

    NSData *data = (NSData*) [[[[NSAppleScript alloc]
    initWithSource:@"tell application \"iTunes\" to return data of artwork
    1 of current track"]  executeAndReturnError:nil] data];
    NSImage *image = [[NSImage alloc] initWithData: data];
    [myImageView setImage:image];

    So I figured this would be the exact same thing, using Script Bridge:

    iTunesApplication *iTunes = [SBApplication
    applicationWithBundleIdentifier:@"com.apple.iTunes"];
    iTunesTrack *current = [iTunes currentTrack];
    iTunesArtwork *artwork = [[current artworks] objectAtIndex:0];
    NSImage *image = [[NSImage alloc] initWithData:(NSData *) artwork];
    [myImageView setImage:image];

    But all I get is a crash:

    2007-11-15 03:11:42.056 bridge[4960:10b] *** -[ITunesArtwork length]:
    unrecognized selector sent to instance 0x13066510
    2007-11-15 03:11:42.058 bridge[4960:10b] An uncaught exception was raised
    2007-11-15 03:11:42.059 bridge[4960:10b] *** -[ITunesArtwork length]:
    unrecognized selector sent to instance 0x13066510
    2007-11-15 03:11:42.059 bridge[4960:10b] *** Terminating app due to
    uncaught exception 'NSInvalidArgumentException', reason: '***
    -[ITunesArtwork length]: unrecognized selector sent to instance
    0x13066510'

    I think the problem is iTunesArtwork is not NSData, but an NSImage:

    @property (copy) NSImage *data;  // data for this artwork, in the form
    of a picture

    How can I read this picture as data, in order to create an NSImage
    imageWithData? I tried with  [[[current artworks] objectAtIndex:0]
    data] and [myImageView setImage:(NSImage *)artwork] to no avail.

    Thanks.
  • No, "current" is an iTunesTrack object. [current data] return a
    compilation error. "artwork" is an iTunesArtwork object. It has no
    -data method. Assuming you meant [artwork data], that would equal
    [[[current artworks] objectAtIndex:0] data] which results in an
    uncaught exception, even though it looks like the equivalent to the
    -data method of the NSAppleScript way to me:

    [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    to return data of artwork
    1 of current track"]  executeAndReturnError:nil] data]

    Thanks.

    On Nov 15, 2007 3:50 AM, Chris Campbell <chris_campbell...> wrote:
    > On Nov 14, 2007, at 9:26 PM, <slasktrattenator...> wrote:
    >
    >> I think the problem is iTunesArtwork is not NSData, but an NSImage:
    >>
    >> @property (copy) NSImage *data;  // data for this artwork, in the form
    >> of a picture
    >>
    >> How can I read this picture as data, in order to create an NSImage
    >> imageWithData? I tried with  [[[current artworks] objectAtIndex:0]
    >> data] and [myImageView setImage:(NSImage *)artwork] to no avail.
    >
    > If your original assumption is correct, then "current" is an
    > ITunesArtwork object, and it has a -data method that returns an NSImage.
    >
    > So do something like:
    >
    > [myImageView setImage:[current data]];
    >
    > Have fun!
    >
    > - Chris
    >
    >
  • On Nov 15, 2007, at 4:49 AM, <slasktrattenator...> wrote:

    > No, "current" is an iTunesTrack object. [current data] return a
    > compilation error. "artwork" is an iTunesArtwork object. It has no
    > -data method. Assuming you meant [artwork data], that would equal
    > [[[current artworks] objectAtIndex:0] data] which results in an
    > uncaught exception, even though it looks like the equivalent to the
    > -data method of the NSAppleScript way to me:
    >
    > [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    > to return data of artwork
    > 1 of current track"]  executeAndReturnError:nil] data]

    When I first started using ScriptingBridge I struggled with a similar
    problem (iTunes add: wants an NSArray - an array of what ? It turns
    out it needs an array of NSURL's).

    To debug this I ran the Script Editor app 'in debug mode' with a small
    handwritten script to mirror my action. To do this set the AEDebugSend
    environment variable in a Terminal window and then launch the script
    editor app from the same terminal session. ScriptEditor will log to
    stdout a dump of the raw events it was sending to iTunes - I could see
    that my posix path was being converted to an 'furl' applevent and from
    their I deduced the NSURL requirement.

    Perhaps a similar trick with the artwork might reveal what the
    underlying types are ? And from there the most likely matching/
    appropriate Cocoa type ?

    Andrew 8-)
  • Thanks for the tip. I tried it, but to my best understanding it didn't
    reveal any secrets. What I could see was that the call returns a PICT
    image with data, but that much I knew already. What bugs me is that
    both the NSAppleScript and the ScriptingBridge approach are supposed
    to return the exact same results, yet

    [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    to return data of artwork 1 of current track"]
    executeAndReturnError:nil] data]

    works, but [artwork data] doesn't... Oh well, I'll keep trying.

    On Nov 15, 2007 4:37 PM, Andrew Kimpton <awk...> wrote:
    >
    > On Nov 15, 2007, at 4:49 AM, <slasktrattenator...> wrote:
    >
    >> No, "current" is an iTunesTrack object. [current data] return a
    >> compilation error. "artwork" is an iTunesArtwork object. It has no
    >> -data method. Assuming you meant [artwork data], that would equal
    >> [[[current artworks] objectAtIndex:0] data] which results in an
    >> uncaught exception, even though it looks like the equivalent to the
    >> -data method of the NSAppleScript way to me:
    >>
    >> [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    >> to return data of artwork
    >> 1 of current track"]  executeAndReturnError:nil] data]
    >
    > When I first started using ScriptingBridge I struggled with a similar
    > problem (iTunes add: wants an NSArray - an array of what ? It turns
    > out it needs an array of NSURL's).
    >
    > To debug this I ran the Script Editor app 'in debug mode' with a small
    > handwritten script to mirror my action. To do this set the AEDebugSend
    > environment variable in a Terminal window and then launch the script
    > editor app from the same terminal session. ScriptEditor will log to
    > stdout a dump of the raw events it was sending to iTunes - I could see
    > that my posix path was being converted to an 'furl' applevent and from
    > their I deduced the NSURL requirement.
    >
    > Perhaps a similar trick with the artwork might reveal what the
    > underlying types are ? And from there the most likely matching/
    > appropriate Cocoa type ?
    >
    > Andrew 8-)
    >
    >
  • The sdef utility gives a header file with all the properties of each
    item. I don't know if that's what you're missing.

    > // a piece of art within a track
    > @interface iTunesArtwork : iTunesItem
    >
    > @property (copy) NSImage *data;  // data for this artwork, in the
    > form of a picture
    > @property (readonly) BOOL downloaded;  // was this artwork
    > downloaded by iTunes?
    > @property (copy, readonly) NSNumber *format;  // the data format for
    > this piece of artwork
    > @property NSInteger kind;  // kind or purpose of this piece of artwork
    >
    > @end

    You get the header file by running:
    > sdef /Applications/iTunes.app | sdp -fh --basename iTunes

    Maybe I'm just repeating stuff that everyone knows, just thought I'd
    share this though.
    Jason

    On Nov 15, 2007, at 10:39 AM, <slasktrattenator...> wrote:

    > Thanks for the tip. I tried it, but to my best understanding it didn't
    > reveal any secrets. What I could see was that the call returns a PICT
    > image with data, but that much I knew already. What bugs me is that
    > both the NSAppleScript and the ScriptingBridge approach are supposed
    > to return the exact same results, yet
    >
    > [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    > to return data of artwork 1 of current track"]
    > executeAndReturnError:nil] data]
    >
    > works, but [artwork data] doesn't... Oh well, I'll keep trying.
    >
    > On Nov 15, 2007 4:37 PM, Andrew Kimpton <awk...> wrote:
    >>
    >> On Nov 15, 2007, at 4:49 AM, <slasktrattenator...> wrote:
    >>
    >>> No, "current" is an iTunesTrack object. [current data] return a
    >>> compilation error. "artwork" is an iTunesArtwork object. It has no
    >>> -data method. Assuming you meant [artwork data], that would equal
    >>> [[[current artworks] objectAtIndex:0] data] which results in an
    >>> uncaught exception, even though it looks like the equivalent to the
    >>> -data method of the NSAppleScript way to me:
    >>>
    >>> [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes
    >>> \"
    >>> to return data of artwork
    >>> 1 of current track"]  executeAndReturnError:nil] data]
    >>
    >> When I first started using ScriptingBridge I struggled with a similar
    >> problem (iTunes add: wants an NSArray - an array of what ? It turns
    >> out it needs an array of NSURL's).
    >>
    >> To debug this I ran the Script Editor app 'in debug mode' with a
    >> small
    >> handwritten script to mirror my action. To do this set the
    >> AEDebugSend
    >> environment variable in a Terminal window and then launch the script
    >> editor app from the same terminal session. ScriptEditor will log to
    >> stdout a dump of the raw events it was sending to iTunes - I could
    >> see
    >> that my posix path was being converted to an 'furl' applevent and
    >> from
    >> their I deduced the NSURL requirement.
    >>
    >> Perhaps a similar trick with the artwork might reveal what the
    >> underlying types are ? And from there the most likely matching/
    >> appropriate Cocoa type ?
    >>
    >> Andrew 8-)
    >>
    >>

  • Thanks, got that already. The code would hardly compile elsewise ;-)

    On Nov 15, 2007 6:50 PM, Jason Ketterman <jason.ketterman...> wrote:
    > The sdef utility gives a header file with all the properties of each item. I
    > don't know if that's what you're missing.
    >
    >
    > // a piece of art within a track
    > @interface iTunesArtwork : iTunesItem
    >
    > @property (copy) NSImage *data;  // data for this artwork, in the form of a
    > picture
    > @property (readonly) BOOL downloaded;  // was this artwork downloaded by
    > iTunes?
    > @property (copy, readonly) NSNumber *format;  // the data format for this
    > piece of artwork
    > @property NSInteger kind;  // kind or purpose of this piece of artwork
    >
    > @end
    > You get the header file by running:
    > sdef /Applications/iTunes.app | sdp -fh --basename iTunes
    >
    > Maybe I'm just repeating stuff that everyone knows, just thought I'd share
    > this though.
    > Jason
    >
    >
    >
    > On Nov 15, 2007, at 10:39 AM, <slasktrattenator...> wrote:
    >
    >
    > Thanks for the tip. I tried it, but to my best understanding it didn't
    > reveal any secrets. What I could see was that the call returns a PICT
    > image with data, but that much I knew already. What bugs me is that
    > both the NSAppleScript and the ScriptingBridge approach are supposed
    > to return the exact same results, yet
    >
    > [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    > to return data of artwork 1 of current track"]
    > executeAndReturnError:nil] data]
    >
    > works, but [artwork data] doesn't... Oh well, I'll keep trying.
    >
    > On Nov 15, 2007 4:37 PM, Andrew Kimpton <awk...> wrote:
    >
    > On Nov 15, 2007, at 4:49 AM, <slasktrattenator...> wrote:
    >
    >
    > No, "current" is an iTunesTrack object. [current data] return a
    >
    > compilation error. "artwork" is an iTunesArtwork object. It has no
    >
    > -data method. Assuming you meant [artwork data], that would equal
    >
    > [[[current artworks] objectAtIndex:0] data] which results in an
    >
    > uncaught exception, even though it looks like the equivalent to the
    >
    > -data method of the NSAppleScript way to me:
    >
    >
    >
    > [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    >
    > to return data of artwork
    >
    > 1 of current track"]  executeAndReturnError:nil] data]
    >
    > When I first started using ScriptingBridge I struggled with a similar
    > problem (iTunes add: wants an NSArray - an array of what ? It turns
    > out it needs an array of NSURL's).
    >
    > To debug this I ran the Script Editor app 'in debug mode' with a small
    > handwritten script to mirror my action. To do this set the AEDebugSend
    > environment variable in a Terminal window and then launch the script
    > editor app from the same terminal session. ScriptEditor will log to
    > stdout a dump of the raw events it was sending to iTunes - I could see
    > that my posix path was being converted to an 'furl' applevent and from
    > their I deduced the NSURL requirement.
    >
    > Perhaps a similar trick with the artwork might reveal what the
    > underlying types are ? And from there the most likely matching/
    > appropriate Cocoa type ?
    >
    > Andrew 8-)
    >
    >
  • <slasktrattenator...> wrote:

    > What bugs me is that
    > both the NSAppleScript and the ScriptingBridge approach are supposed
    > to return the exact same results, yet

    Not true: -[NSAppleScript executeAndReturnError:] always returns an
    NSAppleEventDescriptor which you are responsible for unpacking
    yourself. The type of value returned by Scripting Bridge depends on
    various factors which I can't be bothered listing, but in this case it
    should return an NSImage instance as SB knows how to map between
    AEDescs of typePict, typeTIFF, etc. and the Cocoa equivalent.

    As an aside: don't assume that operations that work in AppleScript are
    always guaranteed to work in Scripting Bridge, or at least not without
    kludgy workarounds. It's a long, long story which I hope to go into
    when I've a bit more time on my hands, but short version is that SB
    has its own rather strong opinions about how Apple event IPC _should_
    work which are not necessarily related to how it actually _does_ work
    in the real world. That isn't the issue here, but if you Google for
    "Scripting Bridge" hits made in the last month, you'll find several
    discussions of compatibility problems, including some relating to
    other aspects of iTunes scripting.

    > [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    > to return data of artwork 1 of current track"]
    > executeAndReturnError:nil] data]
    >
    > works, but [artwork data] doesn't... Oh well, I'll keep trying.

    Note that these two -data methods are not the same.

    The first, -[NSAppleEventDescriptor data], returns an NSData instance
    containing a copy of the AEDesc's raw data; your original
    NSAppleScript example then shoves this data into an NSImage object
    that you can use in the rest of your code.

    The second, -[itunesArtwork data], returns an NSImage instance which
    you should be able to use as-is.

    e.g. The following works here for a track that I dropped a .gif file
    on just to test it:

    #!/usr/bin/python

    from ScriptingBridge import *

    itunes =
    SBApplication.alloc().initWithBundleIdentifier_('com.apple.itunes')

    print itunes.currentTrack().artworks()[0].data()

    Result:

    NSImage 0x2135b70 Size={324, 325} Reps=(
        NSPICTImageRep 0x2135e70 Size={324, 325}
    ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=324x325 Alpha=NO
    )

    If no track is active, or if the active track doesn't have any artwork
    attached, you'll get an object not found error (-1728). If that's not
    the cause of your problem, I suppose it's also possible that there
    could be a bug in the AE-Cocoa picture type mappings. You'd need to
    provide more info on the reported error (and, if it's an SB bug, a
    copy of the problem image) in order to say for sure.

    has
    --
    http://appscript.sourceforge.net
    http://rb-appscript.rubyforge.org
  • Andrew Kimpton wrote:
    >
    > When I first started using ScriptingBridge I struggled with a similar
    > problem (iTunes add: wants an NSArray - an array of what ? It turns
    > out it needs an array of NSURL's).

    Actually, the iTunes dictionary specifies a list of aliases
    (typeAlias) for the 'add' command, but as long as the command is well-
    implemented (i.e. asks the Apple Event Manager to coerce the supplied
    values to the desired type) it should be able to accept file URLs
    (typeFileURL) as well. Cocoa doesn't provide an equivalent to Carbon's
    Alias type, and Scripting Bridge doesn't define an equivalent class
    itself, so I'm assuming it just uses NSURLs in both cases.

    > To debug this I ran the Script Editor app 'in debug mode' with a small
    > handwritten script to mirror my action. To do this set the AEDebugSend
    > environment variable in a Terminal window and then launch the script
    > editor app from the same terminal session. ScriptEditor will log to
    > stdout a dump of the raw events it was sending to iTunes - I could see
    > that my posix path was being converted to an 'furl' applevent and from
    > their I deduced the NSURL requirement.

    Crap documentation tools is certainly one of Scripting Bridge's
    various shortcomings. Unfortunately, Apple haven't published the rules
    by which Scripting Bridge translates AppleScript-style keywords and
    Apple event types to their ObjC equivalents, otherwise I could add a
    'Scripting Bridge' option to ASDictionary [1] which can already export
    very nice HTML-based application dictionaries for AppleScript and
    Python/Ruby/ObjC-appscript.

    However, you shouldn't need to resort to AEDebug to determine type
    info (except perhaps as a last resort): if you look at the
    application's dictionary in Script Editor/Smile/Script Debugger/
    ASDictionary, you can probably guess the desired Cocoa class based on
    the AppleScript type shown - e.g. 'list of Unicode text' would be an
    NSArray of NSStrings; 'list of integer' would presumably be an NSArray
    of NSNumbers; etc.

    You might also want to file a feature request asking that sdp-
    generated headers add a full type description to the comments of
    properties and parameters, e.g.:

    - (itunesTrack *) add:(NSArray *)/*of NSURL*/ x to:(SBObject
    *)to;  // add one or more files to a playlist

    (Incidentally, while on the topic of SB sins, be warned that iTunes'
    'add' command will return either a reference OR a list of references,
    depending on the number of files you give it. Unfortunately, the
    iTunes dictionary is somewhat imprecise in describing the return type,
    so the above sdp-generated declaration ends up with the wrong result
    type.)

    has

    [1] http://appscript.sourceforge.net/download.html
    --
    http://appscript.sourceforge.net
    http://rb-appscript.rubyforge.org
  • Thanks for the detailed explanation. Very enlightening. [[artwork
    data] description] tells me I got an NSImage, just as you:

    NSImage 0x1f5510 Size={944, 921} Reps=(
        NSPICTImageRep 0x109950 Size={944, 921}
    ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=944x921 Alpha=NO
    )

    Yet I can't use this as-is in an NSImageView for some reason. Maybe I
    need to pull the raw data out of the NSPictImageRep first, and create
    an NSImage out of that? But then, how do I do that? I searched the
    archives and it seems awfully complicated. Also, my main concern is
    speed. Would such a conversion be slower than using the NSAppleScript
    approach? Any way I can get the AEDesc's raw data directly from the
    iTunesArtwork property?

    On Nov 15, 2007 9:46 PM, has <hengist.podd...> wrote:
    > <slasktrattenator...> wrote:
    >
    >> What bugs me is that
    >> both the NSAppleScript and the ScriptingBridge approach are supposed
    >> to return the exact same results, yet
    >
    > Not true: -[NSAppleScript executeAndReturnError:] always returns an
    > NSAppleEventDescriptor which you are responsible for unpacking
    > yourself. The type of value returned by Scripting Bridge depends on
    > various factors which I can't be bothered listing, but in this case it
    > should return an NSImage instance as SB knows how to map between
    > AEDescs of typePict, typeTIFF, etc. and the Cocoa equivalent.
    >
    > As an aside: don't assume that operations that work in AppleScript are
    > always guaranteed to work in Scripting Bridge, or at least not without
    > kludgy workarounds. It's a long, long story which I hope to go into
    > when I've a bit more time on my hands, but short version is that SB
    > has its own rather strong opinions about how Apple event IPC _should_
    > work which are not necessarily related to how it actually _does_ work
    > in the real world. That isn't the issue here, but if you Google for
    > "Scripting Bridge" hits made in the last month, you'll find several
    > discussions of compatibility problems, including some relating to
    > other aspects of iTunes scripting.
    >
    >
    >> [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    >> to return data of artwork 1 of current track"]
    >> executeAndReturnError:nil] data]
    >>
    >> works, but [artwork data] doesn't... Oh well, I'll keep trying.
    >
    > Note that these two -data methods are not the same.
    >
    > The first, -[NSAppleEventDescriptor data], returns an NSData instance
    > containing a copy of the AEDesc's raw data; your original
    > NSAppleScript example then shoves this data into an NSImage object
    > that you can use in the rest of your code.
    >
    > The second, -[itunesArtwork data], returns an NSImage instance which
    > you should be able to use as-is.
    >
    > e.g. The following works here for a track that I dropped a .gif file
    > on just to test it:
    >
    > #!/usr/bin/python
    >
    > from ScriptingBridge import *
    >
    > itunes =
    > SBApplication.alloc().initWithBundleIdentifier_('com.apple.itunes')
    >
    > print itunes.currentTrack().artworks()[0].data()
    >
    > Result:
    >
    > NSImage 0x2135b70 Size={324, 325} Reps=(
    > NSPICTImageRep 0x2135e70 Size={324, 325}
    > ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=324x325 Alpha=NO
    > )
    >
    > If no track is active, or if the active track doesn't have any artwork
    > attached, you'll get an object not found error (-1728). If that's not
    > the cause of your problem, I suppose it's also possible that there
    > could be a bug in the AE-Cocoa picture type mappings. You'd need to
    > provide more info on the reported error (and, if it's an SB bug, a
    > copy of the problem image) in order to say for sure.
    >
    >
    > has
    > --
    > http://appscript.sourceforge.net
    > http://rb-appscript.rubyforge.org
    >
  • Correction: has, you were absolutely right. The NSImage can be used
    as-is. The working code is so simple I can't believe it. For anyone
    interested:

    iTunesArtwork *artwork = [[current artworks] objectAtIndex:0];
    [myImageView setImage:(NSImage *)[artwork data]];

    Thought I tried it a thousand times already... {looks away in shame}.

    Thanks all for the help, you're great.

    On Nov 15, 2007 11:06 PM,  <slasktrattenator...> wrote:
    > Thanks for the detailed explanation. Very enlightening. [[artwork
    > data] description] tells me I got an NSImage, just as you:
    >
    > NSImage 0x1f5510 Size={944, 921} Reps=(
    > NSPICTImageRep 0x109950 Size={944, 921}
    > ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=944x921 Alpha=NO
    > )
    >
    > Yet I can't use this as-is in an NSImageView for some reason. Maybe I
    > need to pull the raw data out of the NSPictImageRep first, and create
    > an NSImage out of that? But then, how do I do that? I searched the
    > archives and it seems awfully complicated. Also, my main concern is
    > speed. Would such a conversion be slower than using the NSAppleScript
    > approach? Any way I can get the AEDesc's raw data directly from the
    > iTunesArtwork property?
    >
    >
    >
    > On Nov 15, 2007 9:46 PM, has <hengist.podd...> wrote:
    >> <slasktrattenator...> wrote:
    >>
    >>> What bugs me is that
    >>> both the NSAppleScript and the ScriptingBridge approach are supposed
    >>> to return the exact same results, yet
    >>
    >> Not true: -[NSAppleScript executeAndReturnError:] always returns an
    >> NSAppleEventDescriptor which you are responsible for unpacking
    >> yourself. The type of value returned by Scripting Bridge depends on
    >> various factors which I can't be bothered listing, but in this case it
    >> should return an NSImage instance as SB knows how to map between
    >> AEDescs of typePict, typeTIFF, etc. and the Cocoa equivalent.
    >>
    >> As an aside: don't assume that operations that work in AppleScript are
    >> always guaranteed to work in Scripting Bridge, or at least not without
    >> kludgy workarounds. It's a long, long story which I hope to go into
    >> when I've a bit more time on my hands, but short version is that SB
    >> has its own rather strong opinions about how Apple event IPC _should_
    >> work which are not necessarily related to how it actually _does_ work
    >> in the real world. That isn't the issue here, but if you Google for
    >> "Scripting Bridge" hits made in the last month, you'll find several
    >> discussions of compatibility problems, including some relating to
    >> other aspects of iTunes scripting.
    >>
    >>
    >>> [[[[NSAppleScript alloc] initWithSource:@"tell application \"iTunes\"
    >>> to return data of artwork 1 of current track"]
    >>> executeAndReturnError:nil] data]
    >>>
    >>> works, but [artwork data] doesn't... Oh well, I'll keep trying.
    >>
    >> Note that these two -data methods are not the same.
    >>
    >> The first, -[NSAppleEventDescriptor data], returns an NSData instance
    >> containing a copy of the AEDesc's raw data; your original
    >> NSAppleScript example then shoves this data into an NSImage object
    >> that you can use in the rest of your code.
    >>
    >> The second, -[itunesArtwork data], returns an NSImage instance which
    >> you should be able to use as-is.
    >>
    >> e.g. The following works here for a track that I dropped a .gif file
    >> on just to test it:
    >>
    >> #!/usr/bin/python
    >>
    >> from ScriptingBridge import *
    >>
    >> itunes =
    >> SBApplication.alloc().initWithBundleIdentifier_('com.apple.itunes')
    >>
    >> print itunes.currentTrack().artworks()[0].data()
    >>
    >> Result:
    >>
    >> NSImage 0x2135b70 Size={324, 325} Reps=(
    >> NSPICTImageRep 0x2135e70 Size={324, 325}
    >> ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=324x325 Alpha=NO
    >> )
    >>
    >> If no track is active, or if the active track doesn't have any artwork
    >> attached, you'll get an object not found error (-1728). If that's not
    >> the cause of your problem, I suppose it's also possible that there
    >> could be a bug in the AE-Cocoa picture type mappings. You'd need to
    >> provide more info on the reported error (and, if it's an SB bug, a
    >> copy of the problem image) in order to say for sure.
    >>
    >>
    >> has
    >> --
    >> http://appscript.sourceforge.net
    >> http://rb-appscript.rubyforge.org
    >>
    >
  • On 11/15/07, <slasktrattenator...> <slasktrattenator...> wrote:
    > Thanks for the detailed explanation. Very enlightening. [[artwork
    > data] description] tells me I got an NSImage, just as you:
    >
    > NSImage 0x1f5510 Size={944, 921} Reps=(
    > NSPICTImageRep 0x109950 Size={944, 921}
    > ColorSpace=NSCalibratedRGBColorSpace BPS=0 Pixels=944x921 Alpha=NO
    > )
    >
    > Yet I can't use this as-is in an NSImageView for some reason. Maybe I
    > need to pull the raw data out of the NSPictImageRep first, and create
    > an NSImage out of that? But then, how do I do that? I searched the
    > archives and it seems awfully complicated. Also, my main concern is
    > speed. Would such a conversion be slower than using the NSAppleScript
    > approach? Any way I can get the AEDesc's raw data directly from the
    > iTunesArtwork property?

    You already have an NSImage. Try writing that image out to a file (see
    docs for NSImage to see how to do that) and see if you can open that
    image using preview.

    Also do you get a true or false back if you send that image an isValid message?

    -Shawn
  • On 11/15/07, <slasktrattenator...> <slasktrattenator...> wrote:
    > Correction: has, you were absolutely right. The NSImage can be used
    > as-is. The working code is so simple I can't believe it. For anyone
    > interested:
    >
    > iTunesArtwork *artwork = [[current artworks] objectAtIndex:0];
    > [myImageView setImage:(NSImage *)[artwork data]];

    You shouldn't need the (NSImage*) cast above assuming property
    definition lists NSImage* as the type (or id).

    -Shawn
  • True, not needed. Thanks.

    On Nov 15, 2007 11:38 PM, Shawn Erickson <shawnce...> wrote:
    > On 11/15/07, <slasktrattenator...> <slasktrattenator...> wrote:
    >> Correction: has, you were absolutely right. The NSImage can be used
    >> as-is. The working code is so simple I can't believe it. For anyone
    >> interested:
    >>
    >> iTunesArtwork *artwork = [[current artworks] objectAtIndex:0];
    >> [myImageView setImage:(NSImage *)[artwork data]];
    >
    > You shouldn't need the (NSImage*) cast above assuming property
    > definition lists NSImage* as the type (or id).
    >
    > -Shawn
    >
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today