Get list of wifi networks / tab delimited / airport -s

What I thought would be a simple task is turning my hair grey. I want to grab a list of wifi networks. Using

airport -S

appears to be the best way, but I don’t need to extra bumpf you get, such as:

Woggle’s iPhone5 xx:b3:xx:18:79:61 -29 2 Y – WPA2(PSK/AES/AES)

I know that between each “field” there is a tab, as excel imports it fine as tab delimited

So, here’s the code:


set WifiList to {}

set WifiListRaw to do shell script "airport -s" with administrator privileges
set WifiListNumber to number of paragraphs in WifiListRaw


set tempTID to AppleScript's text item delimiters -- save current delimiters
set AppleScript's text item delimiters to tab

repeat with i from 2 to WifiListNumber
	set LineEntry to text item 1 of paragraph i of WifiListRaw
	if WifiList does not contain LineEntry then set end of WifiList to LineEntry
end repeat

log WifiList

set AppleScript's text item delimiters to tempTID -- restore delimiters

only it doesn’t work. It still sees each text item as the whole line of text :mad:

Any ideas? I’ve thought of finding the first : in the text and working back from there but : is an allowed character in an SSID

Incidentally, changing

	set LineEntry to text item 1 of paragraph i of WifiListRaw

to

	set LineEntry to word 1 of paragraph i of WifiListRaw

does exactly what I want, but any SSID with a space or - in is treated as separate words

Hi,

airport -s | awk '{print $1}'

prints the first field of each line

PS: or use the (AppleScript)ObjC version


property CWInterface : class "CWInterface"

set currentInterface to CWInterface's interface()
set networks to currentInterface's scanForNetworksWithName_error_(missing value, missing value)
set networkNames to networks's valueForKey_("ssid")

You have to link to the CoreWLAN framework

I’d come to this conclusion also but, alas, if there is an SSID that has a space in it, it will report the SSID up to the space only

I appear to be having some issues with this (or am missing something blatantly obvious:

script AppDelegate
	property parent : class "NSObject"
    property CWInterface : class "CWInterface"
	
	on applicationWillFinishLaunching_(aNotification)
        set currentInterface to CWInterface's interface()
        set networks to currentInterface's scanForNetworksWithName_error_(missing value, missing value)
        set networkNames to networks's valueForKey_("ssid")
        log networkNames
	end applicationWillFinishLaunching_
	
	on applicationShouldTerminate_(sender)
		return current application's NSTerminateNow
	end applicationShouldTerminate_
end script

errors with

unrecognized function interface

That means you have to add the framework to the target in Build Phases > Link Binary With Libraries

Stefan,

Many thanks for this. Now working beautifully!

one very last question:

this is returned as an object, or rather list of objects.

Searching on the web hasn’t helped, as I need to then convert these to a list, and this is where I’m struggling…

the variable networks contains a list of CWNetwork objects
the method valueForKey_() returns a list of strings by retrieving the value of the ‘ssid’ property of all objects in networks

Ha! Thought this is very interesting, so I spent some sweat trying to figure out why it didn’t work for me. Kept getting ‘unrecognized function valueForKey_. (error -10000)’ in my face. Which is what happens when you have your Mac wired for speed and Airport switched off :rolleyes:

(Of course that’s what happens when you leave ‘missing value’ and not catch the error parameter…)

Model: iMac
AppleScript: Xcode 4.6
Browser: Safari 536.25
Operating System: Mac OS X (10.8)

This is only a snippet how to retrieve information from CoreWLAN.
Normally you should check


set currentInterface to CWInterface's interface()
if (currentInterface is not missing value and currentInterface's powerOn()) then
	-- get information
end if


That’s right Stefan, so I learned another thing beside how to get networks: always catch the errors, even when just trying out a snippet…

Hi.

Still struggling with this.

I can’t do anything with the output of

set networkNames to networks's valueForKey_("ssid")

other than view it in the log

trying to assign it to a drop down list, or even convert it to a string with

set str to (text items of networkNames) as string

results in:

2013-02-20 17:49:02.737 wifilist[57708:303] *** -[AppDelegate applicationWillFinishLaunching:]: Can’t get every text item of «class ocid» id «data optr000000002086510001000000». (error -1728)

I can’t seem to do anything with this, alas

the result class of valueForKey is an NSSet (a special list which can contain each item only once),
the allObjects() method coerces the set to an NSArray which AppleScript is able to treat as list


set networkNames to networks's valueForKey_("ssid")'s allObjects()

Finally working!

Many thanks for your help Stefan!