Contact Us

Use the form on the right to contact us.

You can edit the text in this area, and change where the contact form on the right submits to, by entering edit mode using the modes on the bottom right. 


Oak Ridge, TN, 37830
United States

Swift-Snips

Filtering by Tag: Array

How to filter an array of dictionaries with NSPredicate : Swift 3

Wade Cantley

This uses a real-world example where beacons are being passed, and I am selectively putting close beacons, which are a dictionary of data, into an array.

The notification that contains all the beacon data is repeated over and over so I don't want duplicates making it into my list, so I use a filter to determine if the Beacon data already exists before appending it to the array.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// I am including lots of "stuff" so that it is clear how this came together in a real example.  
// The code won't work without something feeding becaons to the notification system.  But that doesn't matter.
// The important bits will have /* # */ next to it.
import UIKit
import CoreLocation

class ListBeacons2: UITableViewController {

    // /* 1 */ - Create a varriable that will act as your array container of dictionaries.
    // /* 2 */ - Filter array to see if the new dictionary exists
    // /* 3 */ - If it doesn't append the Dictionary to the array.
    
    
    
    // Setup the variable that will hold the array [] of objects of the type CLBeacon
    /* 1 */ var nearestBeacons = [CLBeacon]()
    
    //....later in code
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Listen for a message containing an array of beacons
        // This comes from another page that sends the package of beacons every time CoreLocation refreshes its search.
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ListBeacons.getAllBeacons),  name: "sendAllBeacons", object: nil)
        
    } //viewDidLoad

    
    func getAllBeacons(notification: NSNotification){
        
        //clear the array
        nearestBeacons = []
        
        // Put the package (that contains the beacons) from the notification into a variable
        var packageOfBeacons = Array(arrayLiteral: notification.object!)
        
        //Put the array of beacons into a variable called "beacons"
        let beacons = packageOfBeacons[0] as! [CLBeacon]
        
        // loop over that array with the contents of type "CLBeacon"
        for eachBeacon in beacons {
            
            // Check the proximity, and if it is close move into the IF
            if (eachBeacon.proximity as CLProximity).rawValue == 1 {
                
                // Filter to see if the beacon already exists in this list.
                // NOTE : We have cast the info coming across as type "CLBeacon" which means that the name of the original key, 
                // such as "uuid" will actually need to be referenced by the object's variable name "proximityUUID".  
                // The casting to a system object of CLBeacon, in line 40, is what does this. 
                /* 2 */let predicate = NSPredicate(format: "%K == %@ AND %K == %@ AND %K == %@" ,
                                            "proximityUUID", eachBeacon.proximityUUID,
                                            "major", eachBeacon.major,
                                            "minor", eachBeacon.minor)
                
                
                let sorted = self.nearestBeacons.filter({
                    return predicate.evaluateWithObject($0)
                })
                
                
                // If there are no beacons like it in the array, append it.
                if sorted.count == 0 {
                    /* 3 */ self.nearestBeacons.append(eachBeacon)
                    print("Added new one")
                    print(eachBeacon)
                }
                
            }
        }
        
        
        
    } // getAllBeacons
}

Here are the contents of the notification... (like 25)

Printing description of notification:
NSConcreteNotification 0x17005ca40 {name = sendAllBeacons; object = (
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:59400, minor:4950, proximity:2 +/- 1.00m, rssi:-77)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:44736, minor:11067, proximity:2 +/- 1.14m, rssi:-85)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:43597, minor:7697, proximity:2 +/- 1.14m, rssi:-85)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:2, minor:24564, proximity:2 +/- 1.67m, rssi:-80)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:1, minor:13719, proximity:2 +/- 2.78m, rssi:-84)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:3, minor:20, proximity:2 +/- 4.08m, rssi:-78)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:3, minor:47301, proximity:2 +/- 4.08m, rssi:-87)",
    "CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:1, minor:20, proximity:3 +/- 3.16m, rssi:-76)"
)}

Here is an example of the contents of "eachBeacon" (line 39)

CLBeacon (uuid:F7826DA6-4FA2-4E98-8024-BC5B71E0893E, major:1, minor:13719, proximity:2 +/- 0.84m, rssi:-72)

 

 

Adding/Appending Objects to an Array : Swift 3

Wade Cantley

The goal here is just to demonstrate how to add an object to an array using a real-world example.  The code is commented and includes an example of a NSPredicate filter.

Look for /* # */ to indicate where that happens.


// I am including lots of "stuff" so that it is clear how this came together in a real example.  
// The code won't work without something feeding becaons to the notification system.  But that doesn't matter.
// The important bits will have /*>*/ next to it.
import UIKit
import CoreLocation

class ListBeacons: UITableViewController {

    // /* 1 */ - Create a varriable that will act as your storage container.
    // /* 2 */ - Append CLBeacon objects to the array.
    
    
    
    // Setup the variable that will hold the array [] of objects of the type CLBeacon
    /* 1 */ var nearestBeacons = [CLBeacon]()
    
    //....later in code
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Listen for a message containing an array of beacons
        // This comes from another page that sends the package of beacons every time CoreLocation refreshes its search.
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ListBeacons.getAllBeacons),  name: "sendAllBeacons", object: nil)
        
    } //viewDidLoad

    
    func getAllBeacons(notification: NSNotification){
        
        //clear the array
        nearestBeacons = []
        
        // Put the package (that contains the beacons) from the notification into a variable
        var packageOfBeacons = Array(arrayLiteral: notification.object!)
        
        //Put the array of beacons into a variable called "beacons"
        let beacons = packageOfBeacons[0] as! [CLBeacon]
        
        // loop over that array with the contents of type "CLBeacon"
        for eachBeacon in beacons {
            
            // Check the proximity, and if it is close move into the IF
            if (eachBeacon.proximity as CLProximity).rawValue == 1 {
                
                // Filter to see if the beacon already exists in this list.
                let predicate = NSPredicate(format: "%K == %@ AND %K == %@ AND %K == %@" ,
                                            "proximityUUID", eachBeacon.proximityUUID,
                                            "major", eachBeacon.major,
                                            "minor", eachBeacon.minor)
                
                
                let sorted = self.nearestBeacons.filter({
                    return predicate.evaluateWithObject($0)
                })
                
                
                // If there are no beacons like it in the array, append it.
                if sorted.count == 0 {
                    /* 2 */ self.nearestBeacons.append(eachBeacon)
                    print("Added new one")
                    print(eachBeacon)
                }
                
            }
        }
        
        
        
    } // getAllBeacons
}

Populate Table From Array

Wade Cantley

The goal here isn't to simply show how you would manage data read into an array from a model class, and then use it to populate cells in a table view.

//  Created by Chris Cantley on 11/13/14.
//  Copyright (c) 2014 Chris Cantley. All rights reserved.
//

import Foundation
import UIKit
import CoreData

class LendersViewController: UIViewController {
   
    //lenders is the array we are going to stick our data into
    var lenders = Array<Lenders>()
    
    // This is the lendersModel class.  This contains our read/write/udpate/delete methods.  For this example we will use a read method to load the table.
    let lendersModel = LendersModel()
   

    //MARK: VC Delegate Methods
    override func viewDidLoad() 
        // Get the data from the read function in the lendersModel class when the view loads.  
        self.lenders = lendersModel.readLenderData() as Array
    }
}

// This extension focusses on containing delegate and custom methods specific to the table view.
extension LendersViewController: UITableViewDelegate, UITableViewDataSource {
   

   
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //return lenderData.count!
        return self.lenders.count
    }
   

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

        // Set the cell to reference the LendersViewCell class below.
        //  This contains all the connections to the cell.
        let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(“SomeCell") as UITableViewCell
    
        var lendersNSArray = lenders as NSArray
       
        var getData = lendersNSArray[indexPath.row].valueForKey("corpName") as String?
        println(getData!)

        return cell
    }
}