martijnwalraven / meteor-ios

Meteor iOS integrates native iOS apps with the Meteor platform (http://www.meteor.com) through DDP
MIT License
740 stars 79 forks source link

What kind of data should return defineStubForMethodWithName? #100

Closed chrisscholly closed 8 years ago

chrisscholly commented 8 years ago

We often see that defineStubForMethodWithName:usingBlock: returns nil. But in which circumstances can we return something other than nil? Can't find this information. Thanks in advance for help :)

martijnwalraven commented 8 years ago

defineStubForMethodWithName:usingBlock itself doesn't return anything, but the block you pass it can return a result.

This result is ignored by default however (just as it is in JavaScript) because the caller can only receive a single result and the assumption is that you want the real result from the server.

You can pass options:METMethodCallOptionsReturnStubValue to callMethodWithName if you do want to receive the returned stub value.

Does this answer your question?

chrisscholly commented 8 years ago

Thanks for your response, it makes sense 👍 But actually, I cannot find any options:METMethodCallOptionsReturnStubValue to be passed to callMethodWithName.

From METDDPClient:

/// @name Performing Method Invocations

public func callMethodWithName(methodName: String, parameters: [AnyObject]?, completionHandler: METMethodCompletionHandler?) -> AnyObject?

public func callMethodWithName(methodName: String, parameters: [AnyObject]?) -> AnyObject?

martijnwalraven commented 8 years ago

Ah, you're right, it's not a public method right now: https://github.com/martijnwalraven/meteor-ios/blob/master/Meteor/METDDPClient_Internal.h#L61

Is this something that would be useful to you? In most cases, you probably want the real result from the server instead.

chrisscholly commented 8 years ago

yes, could be useful I guess. Here's my usecase:

I call a server method with callMethodWithName that inserts a Document. But I would like to have the latency compensation to work as well. So I would define a stub for this method call that inserts the corresponding Document in the local cache and pass the computed documentID from the stub to callMethodWithName so that I can send the document ID as a parameter to the server and perform the server insertion with the same document ID as that of the local cache.

Don't know if it makes sense or if this is the right way to do what I want :p

martijnwalraven commented 8 years ago

Thats sounds way too complicated :) In fact, Meteor iOS will do this for you if you simply insert the document from within the stub (the block you pass to defineStubForMethodWithName:usingBlock:). It will even make sure the ID in the stub and the one on the server are the same.

chrisscholly commented 8 years ago

Oh, ok, nice feature, thanks 👍

Could you confirm that the code below is the right way to do that and that both client/server inserted Documents have the same documentID ?

let chatMessageDocument = ["chatId": 123456789, "msg": "Hello, World!"]

Meteor.defineStubForMethodWithName("chatMessage") { parameters -> AnyObject? in
  Meteor.database.collectionWithName("ChatMessages").insertDocumentWithFields(chatMessageDocument)
  return nil
}  
Meteor.callMethodWithName("chatMessage", parameters: [chatMessageDocument])

Thanks in advance, Chris

martijnwalraven commented 8 years ago

Yes, I believe that should work. But you should probably test it!

chrisscholly commented 8 years ago

Seems to work like a charm, thank you guy! 👍