Re: Identify image file count in directory

2015-11-14 Thread Jonathan Taylor
Hi Gary,

Thanks for your reply. Do you know for sure that this should be significantly 
faster, or were you just guessing? You didn't say which particular API you had 
in mind, but some reading has led me to the fts APIs. These appear to be about 
20% faster than NSFileManager (I specified FTS_NAMEONLY). Better than a kick in 
the teeth, but still seems to me like it might be possible to do it faster.

I measured about 2.5 seconds for a directory on a "Mac OS Extended (Journaled)" 
external USB3 hard disk containing 110,000 files with names around 15 
characters long. I don't know much about how filesystems are structured, so 
this information may not be all in one place, but that should represent less 
than 1MB/s of data read in order to get a list of all the filenames in the 
directory.

Maybe this is as good as it's going to get, but it would be great to know if 
there is a better way.

Jonny.

On 13 Nov 2015, at 16:54, Gary L. Wade  wrote:

> Try going down a level to the BSD layer APIs for directory contents traversal.
> --
> Gary L. Wade (Sent from my iPad)
> http://www.garywade.com/
> 
>> On Nov 13, 2015, at 8:28 AM, Jonathan Taylor  
>> wrote:
>> 
>> Hi all,
>> 
>> I want to be able to identify quickly (programatically) how many image files 
>> reside in a particular directory. At present I call:
>> [NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil];
>> and then examine the type suffixes (which in comparison is very quick). When 
>> looking at a directory over a network or on an external drive, the 
>> NSFileManager call can take several seconds for a directory containing 18k 
>> files of which half are images.
>> 
>> These sorts of numbers are in fact a common use case for me, and I would 
>> like to avoid this delay. This is for preview information in an NSOpenPanel, 
>> so I don't want to make things this unresponsive - but at the same time it 
>> is very useful to have access to this information for the preview.
>> 
>> Can anybody advise on a quicker way of achieving what I want to achieve? The 
>> fact that 'ls' takes almost as long makes me think this is probably a fairly 
>> insurmountable problem, but at the same time the quantity of information 
>> transferred (of the order of 200k of data) should not take 2 seconds to 
>> transfer, so in that sense it doesn't seem unreasonable to try and see if 
>> there is a faster way.
>> 
>> I would prefer to get the filenames themselves, but I could settle for just 
>> a count of the total number of files (of any kind) in the directory *and* 
>> the ability to get the paths of just the first few files in the directory, 
>> if there might be a faster way of doing that.
>> 
>> Thanks for any suggestions
>> Jonny

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

UserDefaults not letting me access a dictionary?

2015-11-14 Thread Alex Hall
Hello list,
Now I've got my Xcode machine back up and running (with an SSD, finally), I'm 
revisiting a couple apps I had paused. In one, I use a dictionary to store 
category filters in UserDefaults in [String:Bool]. I can then use something like

if let filters = userPrefs.dictionaryForKey("filters") {
someFilterSwitch.on = filter[someCategory.rawValue]
}

someCategory is stored in a String enum and is what I use whenever I need that 
string, so it's constant. userPrefs, of course, is just an instance of 
UserDefaults. someFilterSwitch is a UISwitch; I have one for each filter in my 
Filters scene. I use the user prefs to turn them on or off, and update the 
prefs in prepareForSegue in that scene.

In a playground, accessing a dictionary of [String:Bool] works fine, as 
expected. In the app, though, I get an error that I can't index [String:Bool] 
with type 'String'. I don't understand why that is, so wanted to see if there 
was anything special about what UserDefaults returns. In the header file it's 
just an optional dictionary, and my 'if let' takes care of that. I'm not sure 
why else my code would error out right there, though. I haven't played much 
with user preferences before, so I may well be missing something, but it seems 
easy enough to use and there shouldn't be anything funny going on. Any 
thoughts? Thanks!

--
Have a great day,
Alex Hall
mehg...@icloud.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Voiceover support

2015-11-14 Thread Alex Hall

> On Nov 13, 2015, at 08:09, Daniel Phillips  wrote:
> 
> I work at Trainline on their iOS app. We had some customer feedback recently 
> and unfortunately someone booked a ticket for the wrong date because we 
> botched our voiceover support! 
> Safe to say our app as it stands is using accessibility solely for UI Testing 
> purposes and any voiceover functionality is purely coincidence. 
> 
> I've been adding voiceover support and my question is, to what level do you 
> suggest I go with it. By which I mean, we have a lot of data on screen, 
> departure times, departure station name, a label showing the duration of 
> travel in an abbreviated format etc etc. 
> 
> These labels could all be on say a single table view cell.
> 
> I just added support for the following: "2h 25m, direct" to read out "2 hours 
> and 25 minutes. Direct train."
> 
> And then I began work on the departure/arrival time. Then it hit me, I don't 
> really know what I'm going for. It currently reads out something like "10:20. 
> London. 14:36. Manchester", but having added a nicer support in the previous 
> duration example, I'm tempted to have voiceover read something like 
> "Departing 10:20 from London. Arriving 14:36 at Manchester"

Makes sense to me, actually. It's not what is visually there, but I'd rather 
hear that kind of description, since, as a VO user, I can't look at the top of 
the table to see which column is which. Especially when you start throwing 
times around, having clarity is great. It's also good that you've combined all 
these items into a single string, so there's no need to swipe five times just 
to read one cell.
> 
> Of course there's no limit on what you could do with this, but I wanted your 
> thoughts on how far is too far. I want to make sure they get all the info, 
> but is being too chatty a bad thing?

Purely from my perspective as someone who relies exclusively on VoiceOver, I 
think there's a difference between clarity/efficiency and "too far". Too far, 
in my view, would be presenting things that aren't visually there or making a 
whole separate interface to be presented if VO is on. It would also be adding 
way too much extra wording, such as "this train departs from London at exactly 
10:00 in the morning". All you need is "departs London at 10:00" (obviously 
formatting that time to the user's setting). But your example is, I think, well 
within the realm of reasonable. You briefly, but clearly, describe the times 
and destinations, and you use punctuation to break it up and make it easier to 
listen to. Were I to read that on my phone, I wouldn't think twice about it, 
and I'd think what a nice job the devs did making it easier to use.

As I said, though, that's just me--one guy's opinion. I'd suggest two things: 
1) you may want to join accessibility-...@lists.apple.com to ask this; 2) you 
could post a forum topic on www.applevis.com to request feedback from a much 
wider range of people who all use VoiceOver, braille, etc. As I said, though, 
you're definitely on the right track (sorry, bad pun) with what you've done so 
far, IMHO.
> 
> Would love your feedback.
> 
> Daniel
> 
> Sent from my iPad
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/mehgcap%40icloud.com
> 
> This email sent to mehg...@icloud.com


--
Have a great day,
Alex Hall
mehg...@icloud.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Identify image file count in directory

2015-11-14 Thread Gary L. Wade
I've worked on backup, syncing apps, and other file system related utilities 
for some rather well-known companies, so I've definitely explored the speed 
issues you're seeing. At one time I also had explored and used the CoreOS APIs 
that were shared with the legacy Carbon system (FSIterator, etc.). One app I 
refactored to not use Cocoa for just getting the listing of a large file system 
dropped from three minutes to 20 seconds and significantly reduced the memory 
footprint in the process.

The Cocoa frameworks pretty much call these lower level APIs and encapsulate 
their results in Cocoa objects (i.e., HFS+ is not composed of Cocoa objects), 
which can indeed add up when you're looking at the quantity of files you're 
seeing, and uses a lot more memory than needed for your case, which is just 
counting the files that are images, essentially checking the extensions from a 
known set (getting an extension from an NSString is also more expensive than 
traversing a C array of bytes to find the last period). And when you're going 
across a network boundary, the speed in doing more than needed really adds up.
--
Gary L. Wade (Sent from my iPad)
http://www.garywade.com/

> On Nov 14, 2015, at 10:15 AM, Jonathan Taylor  
> wrote:
> 
> Hi Gary,
> 
> Thanks for your reply. Do you know for sure that this should be significantly 
> faster, or were you just guessing? You didn't say which particular API you 
> had in mind, but some reading has led me to the fts APIs. These appear to be 
> about 20% faster than NSFileManager (I specified FTS_NAMEONLY). Better than a 
> kick in the teeth, but still seems to me like it might be possible to do it 
> faster.
> 
> I measured about 2.5 seconds for a directory on a "Mac OS Extended 
> (Journaled)" external USB3 hard disk containing 110,000 files with names 
> around 15 characters long. I don't know much about how filesystems are 
> structured, so this information may not be all in one place, but that should 
> represent less than 1MB/s of data read in order to get a list of all the 
> filenames in the directory.
> 
> Maybe this is as good as it's going to get, but it would be great to know if 
> there is a better way.
> 
> Jonny.
> 
>> On 13 Nov 2015, at 16:54, Gary L. Wade  wrote:
>> 
>> Try going down a level to the BSD layer APIs for directory contents 
>> traversal.
>> --
>> Gary L. Wade (Sent from my iPad)
>> http://www.garywade.com/
>> 
>>> On Nov 13, 2015, at 8:28 AM, Jonathan Taylor 
>>>  wrote:
>>> 
>>> Hi all,
>>> 
>>> I want to be able to identify quickly (programatically) how many image 
>>> files reside in a particular directory. At present I call:
>>> [NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil];
>>> and then examine the type suffixes (which in comparison is very quick). 
>>> When looking at a directory over a network or on an external drive, the 
>>> NSFileManager call can take several seconds for a directory containing 18k 
>>> files of which half are images.
>>> 
>>> These sorts of numbers are in fact a common use case for me, and I would 
>>> like to avoid this delay. This is for preview information in an 
>>> NSOpenPanel, so I don't want to make things this unresponsive - but at the 
>>> same time it is very useful to have access to this information for the 
>>> preview.
>>> 
>>> Can anybody advise on a quicker way of achieving what I want to achieve? 
>>> The fact that 'ls' takes almost as long makes me think this is probably a 
>>> fairly insurmountable problem, but at the same time the quantity of 
>>> information transferred (of the order of 200k of data) should not take 2 
>>> seconds to transfer, so in that sense it doesn't seem unreasonable to try 
>>> and see if there is a faster way.
>>> 
>>> I would prefer to get the filenames themselves, but I could settle for just 
>>> a count of the total number of files (of any kind) in the directory *and* 
>>> the ability to get the paths of just the first few files in the directory, 
>>> if there might be a faster way of doing that.
>>> 
>>> Thanks for any suggestions
>>> Jonny
> 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Identify image file count in directory

2015-11-14 Thread Jens Alfke

> On Nov 14, 2015, at 10:15 AM, Jonathan Taylor  
> wrote:
> 
> Thanks for your reply. Do you know for sure that this should be significantly 
> faster, or were you just guessing? You didn't say which particular API you 
> had in mind, but some reading has led me to the fts APIs. These appear to be 
> about 20% faster than NSFileManager (I specified FTS_NAMEONLY). Better than a 
> kick in the teeth, but still seems to me like it might be possible to do it 
> faster.

If you don’t need to traverse subdirectories, drop down a level to readdir. 
This appears to be the lowest-level public API for directory traversal.

> I measured about 2.5 seconds for a directory on a "Mac OS Extended 
> (Journaled)" external USB3 hard disk containing 110,000 files with names 
> around 15 characters long. I don't know much about how filesystems are 
> structured, so this information may not be all in one place, but that should 
> represent less than 1MB/s of data read in order to get a list of all the 
> filenames in the directory.

Most filesystems get noticeably slower when working with directories containing 
large numbers of items. HFS+ does better than most, but I wouldn’t be surprised 
if a lot of the slowness you’re seeing is just due to filesystem overhead. If 
you can, try dividing up the files among multiple subdirectories and see if 
that helps. (For example, you could create a directory “A” for all the files 
whose names begin with “A”, etc.)

I don’t know exactly how HFS+ stores directory entries, but there’s 
significantly more metadata for a file than just its name, so the filesystem is 
definitely reading more than 15 bytes per file from disk. (For instance, it’s 
pretty likely that 256 bytes are reserved for the filename whether or not all 
of them are used. Then there are the created/modified/used dates, owner/group, 
and probably 8 bytes to store the sector # where the file itself begins.)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: UserDefaults not letting me access a dictionary?

2015-11-14 Thread Quincey Morris
On Nov 14, 2015, at 10:18 , Alex Hall  wrote:
> 
> In a playground, accessing a dictionary of [String:Bool] works fine, as 
> expected. In the app, though, I get an error that I can't index [String:Bool] 
> with type 'String'. I don't understand why that is, so wanted to see if there 
> was anything special about what UserDefaults returns. In the header file it's 
> just an optional dictionary, and my 'if let' takes care of that. I'm not sure 
> why else my code would error out right there, though. I haven't played much 
> with user preferences before, so I may well be missing something, but it 
> seems easy enough to use and there shouldn't be anything funny going on. Any 
> thoughts? Thanks!

You’ve got the types wrong. ‘dictionaryForKey’ returns type [String: 
AnyObject]?, which means — once you’ve stripped the optionality off it — that 
you’re trying to assign from AnyObject to Bool. The error message is confusing, 
because it seems to be saying that your key isn’t a string, but what it 
actually means is that a subscripting operator taking a String key and 
returning a Bool doesn’t exist in class [String: AnyObject], and that’s quite 
true.

You should probably file a bug report about the crappy error message. To fix 
your code you can do something like:

someFilterSwitch.on = filter[someCategory.rawValue] as! Bool

or downcast the dictionary itself to [String: Bool].
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Identify image file count in directory

2015-11-14 Thread Akis Kesoglou
I would suggest to count the number of files asynchronously if possible, so the 
user doesn’t have to wait for this information in order to begin working with 
the panel.

A couple of years ago I had to split by file type an enormous amount of 
restored files from a corrupt hard disk that were inside a few folders, because 
we couldn’t even browse them. The Python script that did the job of moving the 
files around, initially used Python functions and later “ls” to get the list of 
files, but it would get unresponsive for a long time before it started working 
and used tons of memory. I later wrote a simple command line utility that would 
traverse a given directory and print the filenames to stdout in small batches, 
using  “getdirentries()” — try “man getdirentries” and “man dirent” for a 
manual — which, combined with Python’s generators, worked beautifully. 

Anyway, essentially the problem is that “ls” and several system/framework 
functions call down to system routines and wait until all files have been read 
or large buffers are filled before they begin work. Whatever you do, the total 
time it takes to read the contents of a huge directory via lower-level calls 
(i.e. lower-level than Cocoa), will most likely be more or less the same. But 
you can instead do work and update the UI in batches, instead of once in the 
end when you have the total count.

You may find the command line program here [1]. Use it however you like, usual 
disclaimers apply :)

Best,
Akis

[1] https://gist.github.com/dfunckt/055d9a275039d4134558



> On Nov 13, 2015, at 8:28 AM, Jonathan Taylor  
> wrote:
> 
> Hi all,
> 
> I want to be able to identify quickly (programatically) how many image files 
> reside in a particular directory. At present I call:
> [NSFileManager defaultManager] contentsOfDirectoryAtPath:dir error:nil];
> and then examine the type suffixes (which in comparison is very quick). When 
> looking at a directory over a network or on an external drive, the 
> NSFileManager call can take several seconds for a directory containing 18k 
> files of which half are images.
> 
> These sorts of numbers are in fact a common use case for me, and I would like 
> to avoid this delay. This is for preview information in an NSOpenPanel, so I 
> don't want to make things this unresponsive - but at the same time it is very 
> useful to have access to this information for the preview.
> 
> Can anybody advise on a quicker way of achieving what I want to achieve? The 
> fact that 'ls' takes almost as long makes me think this is probably a fairly 
> insurmountable problem, but at the same time the quantity of information 
> transferred (of the order of 200k of data) should not take 2 seconds to 
> transfer, so in that sense it doesn't seem unreasonable to try and see if 
> there is a faster way.
> 
> I would prefer to get the filenames themselves, but I could settle for just a 
> count of the total number of files (of any kind) in the directory *and* the 
> ability to get the paths of just the first few files in the directory, if 
> there might be a faster way of doing that.
> 
> Thanks for any suggestions
> Jonny


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com