4

I have a application which gets audioCDPlayList from iTunes. This app works fine up to macOS High Sierra, but does not work correctly on macOS Mojave Beta 3 (18A326h).

I have investigated the reason and then found that the following strange behavior:

GetAudioCDInfoFromiTunes.h

#import <Foundation/Foundation.h>
#import <ScriptingBridge/ScriptingBridge.h>
#import "iTunes.h"

@interface GetAudioCDInfoFromiTunes : NSObject

   - (NSMutableDictionary *)getAudioCDInfoFromiTunes;

@end

GetAudioCDInfoFromiTunes.m

- (NSMutableDictionary *)getAudioCDInfoFromiTunes {

    // Declear iTunes scripting bridge variable
    iTunesApplication *iTunesApp = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];

    SBElementArray *sources = [iTunesApp sources];
    NSLog(@"sources=%@", sources);
    NSLog(@"count=%ld", [sources count]);

    iTunesPlaylist *aAudioCDPlayList = nil;

    for (iTunesSource *src in sources) {

        NSLog(@"src=%@", src);

        SBElementArray *playlists = [src audioCDPlaylists];

        NSLog(@"playlists=%@", playlists);

        for (iTunesPlaylist *aPlaylist in playlists) {

            NSLog(@"aplaylist=%@", aPlaylist);

            if ([aPlaylist isKindOfClass:[NSClassFromString(@"ITunesAudioCDPlaylist") class]]) {

                aAudioCDPlayList = [aPlaylist get];

                break;
           }
       }
   }

... SNIP ...

}

Executing the above code, NSLog of Line.8, count of sources is 0. And therefore for loop of Line.12 don't work. Then the result [aPlaylist get] is null.

Does anyone know the reason why the count of sources is 0?

Plase let me know how can I run my ScriptingBridge code on Mojave Beta...

xanadu6291
  • 931
  • 10
  • 20
  • Mojave has tightened data security and that includes scripting. It should have prompted you once about allowing your app to control iTunes. You can add your app as an exception in System Preferences > Security & Privacy. See [WWDC 2018 session 702](https://developer.apple.com/videos/play/wwdc2018/702/). – Ken Thomases Jul 14 '18 at 21:36
  • @KenThomases Thanks for your comment. But sadly I'm not a native speaker. I can't understand what WWDC tells me. Yes I was prompted to allow control iTunes. But the most puzzling thing is that executing above code with new Xcode project is OK, but executing as app is bad... Very puzzling... – xanadu6291 Jul 15 '18 at 08:27
  • 1
    There's a transcript tab on that WWDC page, which you can have Google translate, if that helps. There's a developer tool in Mojave that you can use to reset the prompt: `tccutil reset AppleEvents`. That should cause it to prompt again. – Ken Thomases Jul 15 '18 at 13:25
  • @KenThomases Thanks again. I have read Google-translated WWDC session. And then tried your comment's command `tccutil reset AppleEvents` . Then my code suddenly start to working after prompt. Thank you very much!! – xanadu6291 Jul 15 '18 at 15:17
  • @KenThomases If you have time to explain, Would you please tell me the reason the command do a magic. I'm very curious... – xanadu6291 Jul 15 '18 at 15:48
  • You're welcome. I'm glad I could help. Mojave will only prompt once for any given app. It will remember the user's choice. So, you won't be prompted after that. I guess you must have chosen to deny your app the ability to control iTunes once, so it was "permanently" denied. The command `tccutil reset AppleEvents` makes Mojave forget about previous user choices about what apps may control other apps. So, you are prompted again the next time. – Ken Thomases Jul 15 '18 at 16:54
  • To others who may come here: don't forget to set a `NSAppleEventsUsageDescription`. Otherwise, the prompt won't come and your request will silently fail (even after `tccutil reset`!). More info at https://www.felix-schwarz.org/blog/2018/08/new-apple-event-apis-in-macos-mojave – Sören Kuklau Feb 26 '20 at 22:07

1 Answers1

4

Mojave has tightened data security and privacy and that includes scripting. See WWDC 2018 session 702.

The first time your app tries to control iTunes, Mojave will prompt to get your confirmation to allow that. It will remember your choice so it doesn't ask again.

I guess you must have denied it permission once. After that, it just always prevented your app from controlling iTunes.

Since developers need to test their app's behavior when this prompt is displayed, when permission is denied, and when it's granted, Apple has included a command-line utility, tccutil, to reset the remembered user choices. The command to reset permissions regarding which apps may control other apps is tccutil reset AppleEvents.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • I'm not sure either I denied the permission or accepted. Since I don't take a log of my behavior. But may be you are right... Anyway, thanks for your help!! – xanadu6291 Jul 15 '18 at 23:48
  • I have found the steps to reproduce the issue. 1.Allow permission with old version of my app. 2.Try to use new version and it is prevented. 3.Reset AppleEvents with `tccutil`. 4.Prompt again with New version of my app and it can control iTunes. – xanadu6291 Jul 16 '18 at 04:37
  • Hmm. Are you code-signing your development builds? I suspect a properly code-signed app will properly retain permissions through an upgrade. You may wish to file a bug with Apple, though. – Ken Thomases Jul 16 '18 at 11:14
  • Yes both of my app are code-signed properly. OK, I'll inform it to Apple. Thanks for your cooperation!! – xanadu6291 Jul 16 '18 at 16:17