ASObjC Crashes SD

I have a script that is synching files to a network drive. It uses the handler below to get the list of files to synch. It works just fine when the files to synch are on a local drive, but if they’re on another mac, accessed via file sharing, as soon as the script gets to this handler SD hangs (spinning rainbow disc) and must be restarted.

–>Script Debugger 6.0.5 (6A203) on Mac OS 10.11.6 (15G1510) (The other mac is 10.10.5)


on FolderEntireContents(fileORURL)
	set NSFileManager to a reference to current application's NSFileManager
	set NSDirectoryEnumerationSkipsHiddenFiles to a reference to 4
	set NSDirectoryEnumerationSkipsPackageDescendants to a reference to 2
	set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:fileORURL includingPropertiesForKeys:{} options:(NSDirectoryEnumerationSkipsPackageDescendants + (get NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
	set allPosixPaths to (theURLs's valueForKey:"path") as list
end FolderEntireContents

The behavior of Script Editor and when saved as an applet is a little different.

Script editor doesn’t hang, with the rainbow disc, but it does become unresponsive. It seems to stall, the script can’t be closed or stopped.

When saved as an applet it seems to take a while to run that handler, but then starts working.

So after hanging twice, I tried it a third time and it worked.

Your code isn’t going to work under 10.10, because it relies on bridging of files to NSURLs, which was introduced in 10.11. I suggest you use POSIX paths instead. There’s also no need to use a reference to for this stuff outside property declarations. So something like:

on FolderEntireContents(posixPath)
	set NSFileManager to current application's NSFileManager
	set containerURL to current application's |NSURL|'s fileURLWithPath:posixPath
	set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:containerURL includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (get current application's NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
	set allPosixPaths to (theURLs's valueForKey:"path") as list
end FolderEntireContents

Or even:

on FolderEntireContents(fileORURL)
	set NSFileManager to current application's NSFileManager
	if class of fileORURL is in {file, alias} then
		set fileORURL to current application's |NSURL|'s fileURLWithPath:(POSIX path of fileORURL)
	end if
	set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:fileORURL includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (get current application's NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
	set allPosixPaths to (theURLs's valueForKey:"path") as list
end FolderEntireContents

Thanks. I’ll try that.

As for the script on El Capitan, what happens is that as the script is running when it gets to the handler above SD stalls. I get the swirly rainbow, the doc says SD is not responding, and it does this longer than the appleScript time out, but if I just let it be, it returns a result and the script resumes.

If there are a lot of files and it’s a remote volume, that’s entirely likely behavior. In Objective-C, you generally use an enumerator to, well, enumerate as you go, to avoid this very thing. In other words, you get a file from the enumerator, do your stuff to it, then move to the next, and so on, rather than wait for the enumerator to get all the files (allObjects()).

If you’re always dealing with a remote disk, that can be a better approach. So something along these lines:

on doSomethingWithFolderEntireContents(posixPath)
	set NSFileManager to current application's NSFileManager
	set containerURL to current application's |NSURL|'s fileURLWithPath:posixPath
	set theEnumerator to NSFileManager's defaultManager()'s enumeratorAtURL:containerURL includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (get current application's NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value)
	repeat
		set aURL to theEnumerator's nextObject()
		if aURL is missing value then exit repeat -- no more left
		-- if you need the path instead of a URL then...
		set thePath to aURL's |path|() as text
		-- now do something with thePath or aURL here

	end repeat
end doSomethingWithFolderEntireContents

This is less efficient with local volumes, obviously, but depending what you’re doing, on remote volumes it will be more responsive.

Of course if all you care about is speed, you just live with the unresponsiveness…

Is there a way to filter that? Every file of entire contents whose name contains mp3 or m4p.

Here’s the deal, I tried iTunes match on our macs and didn’t like it (mainly didn’t like paying for it). When I turned it off it left our iTunes libraries in a bad state. Music files in the cloud we didn’t have access to and files not stored on our macs. (We upgraded macs, so they weren’t installed on the new macs). Our iPhone are now useless a iPods because they only work when we have wifi or good cell service.

So I’ve got a script that is going through the iTunes music folders on all the various macs and drives where they’ve been stored ever since we first ripped all our CDs to mac, and storing them on a server in a single music file library, structured like an iTunes library. This handler does the initial heavy listings, getting a list of files. Then another handler figures our what that file’s hierarchy would be in the library, looks to see if there’s a version of that file in the library. If there is one and it’s older, it replaces it. If there isn’t one it uploads it. The reason I may want to filter is it’s also finding .itc files (or something like that) which iTunes uses for album artwork, but when I create a new library I don’t think the current art files will link to the files in the new library, so it’s just a waste of time, space and bandwidth.

So some of the volumes will be remotely mounted. Some will be connected via USB. Some will be run locally.

Once I’ve got all the files from all the libraries in one place then I’ll have to import them to iTunes. From there we (everyone in the family with a mac) will build play lists to copy to their macs, and from there to their iphones.

The network volume will serve as a back up for everyone’s music.

Wow! Really? I think iTunes Match is one of the all-time best deals, at a mere $25/year.

I use it with my Apple TV to provide outstanding music to my high-end home theater. It provides me with CD-quality music sync to all of my devices, so I never have to worry with tasks like the one you’re struggling with.

How much is your time worth? I’m guessing at least 7¢/day. LOL

Sure. You use a predicate, which is a bit like a whose clause:

on entireContents:fileORURL withExtensions:extList
	set NSFileManager to current application's NSFileManager
	if class of fileORURL is in {file, alias} then
		set fileORURL to current application's |NSURL|'s fileURLWithPath:(POSIX path of fileORURL)
	end if
	set theURLs to (NSFileManager's defaultManager()'s enumeratorAtURL:fileORURL includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (get current application's NSDirectoryEnumerationSkipsHiddenFiles)) errorHandler:(missing value))'s allObjects()
	-- define predicate and filter array
	set thePred to current application's NSPredicate's predicateWithFormat:"pathExtension IN %@" argumentArray:{extList}
	set theURLs to theURLs's filteredArrayUsingPredicate:thePred
	set allPosixPaths to (theURLs's valueForKey:"lastPathComponent") as list
end entireContents:withExtensions:

my entireContents:(path to music folder) withExtensions:{"mp3", "m4p"}

Even with iTunes match our iPhones wouldn’t work as iPods. We’d have to have wifi, or use cel tower range or it doesn’t work.

They can if you want them to. Just download all (or selected) songs to your iPhone. I’ve done this, and also to one of my Macs, and it works very well.

Maybe it’s working better now. Before a long road trip when we had iTunes match I downloaded a bunch of songs to my mac, then thought I uploaded them to our phones, but when we got out of cell range it shut off and the only songs actually on our iPhones were the ones we had recently purchased. When I got home I complained to apple, actually went in and talked to a genius and they didn’t know why it didn’t work.

When the bill came up for renewal I said no thanks. (Although it literally saved the company and the recording industry, iTunes is and always has been a hot mess.)

I’ve been downloading all songs to my iPhones since iTunes Match was introduced, and have never had a problem. I created a playlist for all songs, and just downloaded it. There is an indicator that shows when the playlist is download, and when a song is not downloaded. Like all things with computer file transfer, it is always best to verify before you leave home.

Then, once we turned off iTunes match, we lost songs. Songs that had been downloaded to our macs just disappeared. These were songs that we’d had before, not purchased through the iTunes store, and one of the reasons I’m doing this script is to try to retrieve them from our various libraries on old macs, or drives retrieved from old macs.

I’m glad you had a good experience with it, but for me (and a lot of others) it was a pain.

I’m not sure, but that may be expected behavior. If you are no longer paying for the service, then you don’t have rights to use it.
iTunes Match provides an enhanced service, providing you with (potentially) better quality songs that your original source, and on ALL of your devices, not just the original source device. The only songs I would expect to have after turning it off are my original source songs.

I can tell it was for you, but I wonder if it is a user issue? :wink:

I have no idea what you mean by “a lot of others”. At any given time there are always a number of users (out of many hundreds of millions) that have some kind of iPhone issue. I’m sure some of the issues are real, but I think a lot are self-induced. I’ve rarely had an issue. But then, with iOS, like all of software, I never upgrade immediately. I’ve waited months in some cases. Seems to pay off.

Well, I think we have about beat this to death. I’ll give you the last word if you want it.

As I said, I went to the apple store with my laptop and my iPhone and they couldn’t explain why the files weren’t on the iPhone. Their advice was to wait for the next upgrade.

A lot of people means I visit a number of mac user groups and this wasn’t uncommon.

I was going to give you the last word, but you have posted a link to a different issue/cause. The above blog (and related blogs) are about people losing music due to “Apple Music” service, NOT “iTunes Match”. See:

Apple Music Deletes Music

Maybe you’re confusing your issue with Apple Music rather than iTunes Match.

Could be, but the files disappeared when I turned off iTunes match. Whether the cause was apple music, iTunes match, iTunes, or even if it was me (and others) making a simple mistake, I don’t really care.

It’s worth it for me to spend a few hours gathering and backing up and permanently storing all the music that’s ever been on any of my macs than trust iTunes to do the same thing.

I totally agree with that. Good luck, I hope it all goes well.