Friday, January 28, 2022

#1 2021-07-30 02:19:03 am

Ptujec
Member
From:: Slovenia
Registered: 2009-01-17
Posts: 10
Website

Filter contacts by zip code

Hi!
I managed to build a script to filter contacts by zip code.
Unfortuantely it is very slow. Does anyone know how to make this faster by using ASOC?

Here is my script:

Applescript:


tell application "Contacts"
   set _ids to every person whose zip of first address starts with "82"
   set _names to {}
   repeat with _id in _ids
       set _name to name of _id
       set the end of _names to _name
   end repeat
   return _names
end tell

Offline

 

#2 2021-07-30 11:03:53 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5475

Re: Filter contacts by zip code

Hi.

Something like this?

Applescript:

use AppleScript version "2.5" -- Mac OS 10.11 (El Capitan) or later.
use framework "Foundation"
use framework "Contacts"

on join(listOfText, delimiter)
   set astid to AppleScript's text item delimiters
   set AppleScript's text item delimiters to delimiter
   set txt to listOfText as text
   set AppleScript's text item delimiters to astid
   return txt
end join

on run argument
   -- set argument to {"82"}
   if (argument's class is list) then set argument to beginning of argument
   set |⌘| to current application
   set contactStore to |⌘|'s class "CNContactStore"'s new()
   -- Request one copy of every contact of every container (although there's probably only one container)
   -- along with their names, addresses, and IDs and build a single mutable array of all the results.
   set allContainers to contactStore's containersMatchingPredicate:(missing value) |error|:(missing value)
   set contactArray to |⌘|'s class "NSMutableArray"'s new()
   set keysNeeded to |⌘|'s class "NSArray"'s arrayWithArray:({|⌘|'s CNContactGivenNameKey, |⌘|'s CNContactFamilyNameKey, |⌘|'s CNContactOrganizationNameKey, |⌘|'s CNContactTypeKey, |⌘|'s CNContactPostalAddressesKey, |⌘|'s CNContactIdentifierKey})
   repeat with thisContainer in allContainers
       set contactPredicate to (|⌘|'s class "CNContact"'s predicateForContactsInContainerWithIdentifier:(thisContainer's identifier()))
       set theseContacts to (contactStore's unifiedContactsMatchingPredicate:(contactPredicate) keysToFetch:(keysNeeded) |error|:(missing value))
       tell contactArray to addObjectsFromArray:(theseContacts)
   end repeat
   
   -- Filter the array for contacts having any address with a post (zip) code beginning with the given argument.
   set zipFilter to |⌘|'s class "NSPredicate"'s predicateWithFormat_("ANY postalAddresses.value.postalCode BEGINSWITH %@", argument)
   tell contactArray to filterUsingPredicate:(result)
   
   -- Get the previously requested info re the survivors' given names, family names,
   -- and/or organisation names, and IDs, coercing the results to AppleScript lists of text.
   set givenNames to (contactArray's valueForKey:("givenName")) as list
   set familyNames to (contactArray's valueForKey:("familyName")) as list
   set organisationNames to (contactArray's valueForKey:("organizationName")) as list
   set contactTypes to (contactArray's valueForKey:("contactType")) as list
   set IDs to (contactArray's valueForKey:("identifier")) as list
   
   -- Collate the results, constructing the names according to contact type.
   set _results to {}
   repeat with i from 1 to (count contactTypes)
       if (item i of contactTypes is 0) then -- Person.
           set _name to (item i of givenNames) & space & (item i of familyNames)
       else -- item i of contactTypes is 1 (organisation)..
           set _name to (item i of organisationNames)
       end if
       set end of _results to "{'title':" & quoted form of _name & ",'icon':'personTemplate.png','url':'addressbook://" & item i of IDs & "'}"
   end repeat
   
   -- Coerce the results list to a single text.
   -- It's best practice always to set Applescript's text item delimiters explicitly for this.
   return join(_results, ",")
end run

Edit: Modified in the light of the reply immediately below.

Last edited by Nigel Garvey (2021-07-31 03:34:52 am)


NG

Offline

 

#3 2021-07-30 01:55:07 pm

Ptujec
Member
From:: Slovenia
Registered: 2009-01-17
Posts: 10
Website

Re: Filter contacts by zip code

Thank you! This performs sooo much better.

I developed my script a bit further in the meantime for use within my LaunchBar action. I mainly added the entry ID. This way I can directly open a given result in Contacts (with some cleanup in the javascript part of my LaunchBar action)
I just don't know how to integrate the ID part in your version. I guess I need to learn ASOC eventually.

Again, thank you!

Applescript:


on run (argument) -- e.g. "82"
-- set argument to "82
   tell application "Contacts"
       set _persons to every person whose zip of first address starts with argument
   end tell

   set _results to {}
   repeat with _person in _persons
       set _name to name of _person
       set _id to id of _person as string
       set _result to "{'title':'" & _name & "','icon': 'personTemplate.png', 'url':'addressbook://" & _id & "'},"
       set the end of _results to _result
   end repeat

   set output to _results as string
   return output
end run

Last edited by Ptujec (2021-07-30 01:59:14 pm)

Offline

 

#4 2021-07-30 08:14:35 pm

robertfern
Member
Registered: 2011-11-29
Posts: 117

Re: Filter contacts by zip code

Here is a shortened version of the first script in post #1

Applescript:


tell application "Contacts"
   set _names to name of every person whose zip of first address starts with "82"
end tell
return _names

Last edited by robertfern (2021-07-31 08:10:48 am)

Offline

 

#5 2021-07-31 03:39:01 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 5475

Re: Filter contacts by zip code

Ptujec wrote:

I just don't know how to integrate the ID part in your version. I guess I need to learn ASOC eventually.


I've modified the script to behave more like your script in post #3.


NG

Offline

 

#6 2021-07-31 01:32:13 pm

Ptujec
Member
From:: Slovenia
Registered: 2009-01-17
Posts: 10
Website

Re: Filter contacts by zip code

Awesome! Thank you so much. It works great. Also thanks for the infos in the comments.

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)