Container Help Needed...

I am trying to learn the Contacts Framework and would very much appreciate someone explaining the following:

What a container is; and

What a container id is and how they work.

Specifically, in the following code I understand that the constant predicate is used to filter the individual contacts that are fetched and stored in array contacts but I do not understand how / why line 42 and 44 work to filter (i.e. include) all contacts.

https://www.dropbox.com/s/um0pkbl7ks4pz7v/20200331_container%20related%20code.png?dl=0

I tried searching the web, YouTube, etc. and all the examples / explanations were far too complicated.

Thanks.

It may be the same as in iTunes.

In iTunes a container is a playlist, folder,
library type ie Music, Movies etc.

ITunes applescripts refers to items.
These can be a playlist, folder, song, movie etc.

So think of the “container” being exactly that.
It contains items.

So a list of items that are songs could be
In a container that is a playlist.

There could be item(s) that are playlists
In a container that is a folder.

If your using Script Debugger, the Dictionary Inspector
Has a hierarchy mode that you can use to help you visualize
How properties/classes are related.

PS it looks like your code is in Swift and not Obj-C

It’s also working with core data.
The containerID is more referring to the contacts default database ID
The predicate is filtering out just those contacts.

If you look in your ~/Library/Contacts/ folder you’ll
See a bunch of different IDs of folders.

I would recommend you use Xcode’s documentstion to learn more
About the contacts framework.
Or online

https://developer.apple.com/documentation/contacts?language=objc

This page discusses more of the CNContactStore usage:
https://developer.apple.com/documentation/contacts/cncontactstore?language=objc

Note where they say: fetch all contacts for an identifier
(That’s what the code you posted is doing)
Then you can further filter.

Objective-C versions:
(get default container)
https://developer.apple.com/documentation/contacts/cncontactstore/1403159-defaultcontaineridentifier?language=objc

(Container predicate filtering)
https://developer.apple.com/documentation/contacts/cncontactstore/1403238-containersmatchingpredicate?language=objc

@techomorph, allow me to start by thanking for your response, it is very much appreciated.

As far the language is concerned, you are correct, it is Swift.

As far as the links that you posted I had already visited most of them as well as spending a fair amount of time scouring the internet.

As far as the specific problem is concerned it is as follows:



       let containerId = store.defaultContainerIdentifier()
        
       let predicate = CNContact.predicateForContactsInContainer(withIdentifier: containerId)

       let keysToFetch = [CNContactGivenNameKey as CNKeyDescriptor,
                           CNContactFamilyNameKey as CNKeyDescriptor,
                           CNContactPhoneNumbersKey as CNKeyDescriptor,
                           CNContactImageDataAvailableKey as
                           CNKeyDescriptor,
                           CNContactImageDataKey as CNKeyDescriptor]

        let contacts = try! store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch)




  1. In terms of the first line, I understand that it returns the default container id for the variable store.

  2. In terms of the second line, I understand that it returns the default container id for the CNContact. I also understand that this predicate will be used to filter / select the contacts that are fetched.

  3. In terms of the second line, what I do not understand and apologies in the event I am not expressing this clearly are the following:

    a) What the “withIdentifier: containedId)” does and why it is needed.

    b) What I thought would work – this is probably wrong – is that the predicate to be used for the fetch would be what the CNContact container predicate was.

With that, you will conclude that I am very confused so that any and all help you can provide in helping me understand this would be great.

Thx!

First I’ll have to say by continuing to request help
With Swift would be offtopic.

This section is for ApplescriptObj-C.
And many direct Objective-C questions I think could
Still be related to ASObj-C. And often translate-able to
ADObj-C. Swift is a different story.
———-
2nd those links when I read them, things were pretty clear to me now.
I’ll admit when I was learning AppleScript, the ASObj-C those pages
Would have been confusing. I’ve learned and developed and my interest
In ASObj-C lead me to learn more directly about Objective-C.
Which in turn has lead me to be almost only using Objective-C.

=============••••

So where are you programming at?
How are you trying to implement this code?
In what programming environment / IDE are you using?

One of the most important things to note in your post is:
What are you trying to achieve?
Many folks will gladly help you with that and give you many
Options, even based on code your using or have found.
Even if it’s not in ASObj. Some folks post “how might I do something
Like this Java code is AppleScript”

======•=••••••••••

The 1st line is giving you a variable of the default containerID

From what I’m feeling from you is that you should learn more about Predicates.

The second line is creating a predicate, that will (filter) only include CNContacts
That are in the container that has the ID of containerID

The next is creating an array of the Keys from each CNContact that you want to fetch.

The last line will give you an array of contacts.
Fetching from the default Contacts store.
First it will fetch only contacts from the predicate.
And then it will on get the Keys created above for each contact.
Rather than giving you all of the properties (all keys) for each contact.

In this case only the 1st name, family names, phone numbers, is an image available, and image data.

It will not return emails, addresses, etc .

@technomorph, thank you for the above information noting that it was never my intention to offend anyone by posting in the incorrect forum. I concluded – and wrongly so – that Swift was fair game in a section that included Xcode. Again, apologies to you and anyone else that I offended; there was zero intent.

In addition, I am brand new to this as learning Swift is my COVID-19 distraction rather than binging on Netflix, etc. I think it is more productive and useful way to spend my time.

I am trying to teach myself and – as you correctly noted above and like you – I have read all / most of the documentation on the Contacts framework and am confused. On this point, how long did it take for things to make sense to you and what did you to do to digest it?

I agree completely, I do need to learn more about Predicates and a whole lot more. I am stuck after spending hours pouring through the internet including Apple documentation, YouTube videos and a whole lot more.

In terms of the fist line of text I completely get it / understand.

In terms of the second line of text this is ONLY THING that confuses me noting:

a. I understand that the second line is creating a predicate that will filter / include only the contacts that are in the container with that predicate.

b. What I do not understand is the portion of the code that reads (withIdentifer: conatinerID) because I would have thought that the predicate could have been decalred to whatever the Contact default container ID was without the need to specify it as store’s container ID per the first line.

That said, is the explanation / idea that in the earlier code that store was declared as let store = CNContactStore() so that store has / inherited Conact’s container ID so that all that is essentially happening is that the second line is declaring the predicate based on Contact’s known container ID?

While I hope the above is clear and properly explains my confusion please let me know in case it is not and I will try once again!

@technomorph, thank you, this I clearly / completely understand including that the resulting array is an array of individual contacts with each individual contact itself being an object with various properties!

I have progressed further in my efforts and would appreciate some additional assistance as follows:

  1. I have written some additional Swift code to access each contacts phone number. The Swift codes for the 2 contact in the array of contacts appears as follows:


        var phone : CNPhoneNumber?

        for item in contacts[2].phoneNumbers {

                print(" ")
                print("Now printing item")
                print("\(item)")

                print("")
                print("Now printem item.label")
                print("\(String(describing: item.label))")
               
                print("")
                print("Now printing item.value")
                print("\(item.value)")
                
            if item.label == "Mobile" {
                    phone? = item.value
                    print("Individual phone number")
                    print("\(String(describing: phone))")
                }
            }

               

  1. While I have been success at extracting the label and value for each CNPhoneNumber property (i.e. home / mobile / etc.) as demonstrated by the below output I am at a loss as to how to extract / fetch the label string (i.e. Home or Work) and the label value (i.e. theactual phone number)
  1. Would appreciate any and all help in as to how to extract / fetch the label string (i.e. Home or Work) and the label value (i.e. the actual phone number).

Thanks!

Ask for the item.value.stringValue

The 1st line gives you a value for
The predicate:

The predicate takes
That value and filters.

Again research more about predicates

@technomorph, thank you, much appreciated…