0

i have a Problem.
I am working with a Graph Database. For each User i want to write a List of Artists to a database. I call my saveProfileData and now the Artist should be added to the Database one by one. But the executeCypher Method(from another api) does not get called after the addArtistsToDatabase gets called, but some time later. So not all Artists are written to the Database. I want to implement my Method that for each artist the actual Artist gets written to the Database, and waits until its completed. I am quite new to Swift and don't know how to solve this.

func saveProfileData(){
    let p = self.profile
    ...
        //add Artists
        for a:Artist in p.artists{
            self.addArtistToDatabase(a)
        }
}

func addArtistToDatabase(a: Artist){

    let cyperQuery: String = "MATCH (a:Artist) WHERE a.id IN [\"\(a.id)\"] RETURN a"
    let cyperParams: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()

    client.executeCypher(cyperQuery, params: cyperParams, completionBlock: {(cypher, error) in
        print("response from cyper \(cypher)")
        //check if result is empty
        let response = cypher?.data

        var isEmpty: Bool = false
        if((response?.count) == 0){
            isEmpty = true
        }
        if(isEmpty){
            //if so create new node for each artist and add the relationhip between artist and user
            let cyperQuery1: String = "CREATE (n:Artist {id:\"\(a.id)\", name:\"\(a.name)\"})"
            let cyperParams1: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
            self.client.executeCypher(cyperQuery1, params: cyperParams1, completionBlock: {(cypher, error) in
                print("response from cyper \(cypher)")
            })

            let query: String = "MATCH (a:User),(b:Artist) WHERE a.id=\"\(self.profile.id)\" AND b.id=\"\(a.id)\" CREATE (a)-[r:ListenTo {interested: \"\(a.display)\"}]->(b) RETURN r "
            let params: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
            self.client.executeCypher(query, params: params, completionBlock: {(cypher, error) in
                print("response from cyper \(cypher)")
            })

        }else{
            //update relationship
            let query: String = "MATCH (n:User {id:\"\(self.profile.id)\"})-[r:ListenTo]->(a:Artist {id:\"\(a.id)\"}) SET r.interested = \"\(a.display)\" RETURN r"
            let params: Dictionary<String, AnyObject> = Dictionary<String, AnyObject>()
            self.client.executeCypher(query, params: params, completionBlock: {(cypher, error) in
                print("response from cyper \(cypher)")
            })
        }
    })

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
hannes
  • 519
  • 4
  • 11
  • 23
  • 1
    What you have is a Code A that needs to call Code B. When Code B is done it should notify you (success or failure) and Code A will act on that response. You don't specify if the saving is local or to the network (which brings up other issues). Google for "delegation design pattern ios". Some of that is also covered in this link: http://stackoverflow.com/questions/6168919/how-do-i-set-up-a-simple-delegate-to-communicate-between-two-view-controllers. NSNotifications may also handle what you need so you may want to read up on that. – xdeleon Dec 09 '15 at 21:03
  • 1
    For this type of execution it is better to use **closures**. – Pushpa Y Dec 10 '15 at 06:54
  • thanks @Pushpa, now i have understood how closures work – hannes Dec 17 '15 at 13:07

0 Answers0