siegesmund / SwiftDDP

A Meteor client, written in Swift
MIT License
145 stars 60 forks source link

How to get a collection after subscription? #51

Closed RonGafni closed 8 years ago

RonGafni commented 8 years ago

Hey everyone,

"userLoginData" - Give my all the information about the current user.

I'm trying to get collection from subscription(called "userLoginData") and i can't figure it how should I get the collection after sign in.

AppDelegate.swift

`let users = MeteorCollection<User>(name: "users")

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.

        Meteor.client.logLevel = .Debug

        Meteor.connect(URL) {

        }

        return true
    }
    ` 

LoginViewController.swift

`Meteor.loginWithPassword(usernameTextField.text!, password: passwordTextField.text!) { (result, error) in

        if (error != nil) {
            print("user not found")

        }else{

            Meteor.subscribe("userLoginData") {
                self.performSegueWithIdentifier("LoginScreenToMessagesScreenSegue", sender: self)

            }

        }

    }`

and after that In MessagesViewController.swift I want to get all the information about the user(address, email, phone number etc..). How can I do this??

Thanks!!

sefasenturk95 commented 8 years ago

Hi @RonGafni

What is the result in your console when executing this code?

let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
print(appDelegate.users.sorted)
RonGafni commented 8 years ago

[onestage.User]) $R0 = 1 value { [0] = 0x00007f951c3490a0 { SwiftDDP.MeteorDocument = { ObjectiveC.NSObject = { isa = onestage.User } _id = "tihSmRZiJCfWCE32e" } _id = nil emails = 1 element { [0] = 0x00007f951c357920 2 key/value pairs } firstName = nil } }

siegesmund commented 8 years ago

It looks to me like you're getting your user data. It's returned as an array of MeteorDocuments, not JSON nor a dictionary, so you can access the data accordingly. Get the user from the array, then access its' properties.

RonGafni commented 8 years ago

ok, but how "userLoginData" get update? which method get called when there is update from the subscription?

This is what I'm getting but how do I access all the fields?

Debug] [DDP] [DDP Background Data Queue :: NSOperation 0x7fc139463c50 (QOS: BACKGROUND)] [221] ddpMessageHandler > Received message: { collection = users; fields = { availability = { chatHours = ( ); type = "OFFICE_HOURS"; };

(there is more field)

sefasenturk95 commented 8 years ago

userLoginData gets updated automatically, you can watch for updates by subscribing to this observer: NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourViewController.yourMethod), name: METEOR_COLLECTION_SET_DID_CHANGE, object: nil)

You can access the fields like this: appDelegate.users.sorted._id

RonGafni commented 8 years ago

This is my User meteorDocument:

`import SwiftDDP

class User: MeteorDocument {

    var _id:String?
    var emails: NSMutableArray?
    var firstName: String?
}
`

but SwiftDDP need to build for me all the other fields from the subscription?

siegesmund commented 8 years ago

In this case you'll need to create a custom user collection & class. You can do this by subclassing MeteorCollection and MeteorDocument. See the docs for how to do this.

RonGafni commented 8 years ago

Ok now its work great!! Thanks

But how meteor know the different between custom collection when I'm using this code?

`NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(yourViewController.yourMethod), name: METEOR_COLLECTION_SET_DID_CHANGE, object: nil)

`
siegesmund commented 8 years ago

@RonGafni - I'm not sure I understand exactly what you're asking.

andrew-buksha commented 8 years ago

Hello. There is already couple of questions on this subject, but I didn't found an answer to my problem, so I hope it's OK if I ask here. I have a collection declared like so:

let myCollection = MeteorCollection<MyCollection>(name: "my-collection") I subscribe to this collection using method: Meteor.subscribe("my-collection")

So I got my collection properly when I retrieve it for the first time. But I want to get updates for it - when collection updates on the server I want to get updated data in client as well.

I added observer to notification METEOR_COLLECTION_SET_DID_CHANGE, and I get it sent when collection updates:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(myViewController.updateCollection), name: METEOR_COLLECTION_SET_DID_CHANGE, object: nil)

This is how my class looks like:

let myCollection = MeteorCollection<MyCollection>(name: "my-collection")

func viewDidLoad() {
   super.viewDidLoad()
   NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(myViewController.updateCollection), name: METEOR_COLLECTION_SET_DID_CHANGE, object: nil)
   Meteor.subscribe("my-collection")
}

func updateCollection() {
   let collectionData = myCollection.sorted
   // Update UI with new data
}

The problem is when I get selector called I can't retrieve updated collection. When collection changes on server and I get notification thrown, when I perform myCollection.sorted, it returns me old data that myCollection was initialized with for the first time. But I can track that my new data gets received when I add breakpoint on self.setValue(value, forKey: key as! String) method in MeteorDocument class. I think I missed some method in my notification selector, but can'y figured out what it could be.

siegesmund commented 8 years ago

It's not clear to me what you're doing from the code you've posted. By class, I assume you mean your ViewController, but there's not a lot of context here.

But several things: Your data should update automatically in your collection when changes are made on the server. If this is not happening, first make sure that your collection name on the client is exactly the same as the collection name on the server.

Then enable logging on the client. You should be able to see each message as it's received by the client. This will help narrow down where the problem is.

Finally, I see that you're subscription has the same name as your collection. Is this correct? I ask because you subscribe to a publication, not to a collection. Although they can seem like the same thing in simple contexts, they're not. Is your publication set up correctly on the server?