Backendless Support
 
Provide More Info

Swift - Backendless error in hosted custom service

I am trying to use a `hosted custom service` in `Backendless`

I created a custom `jar library`and uploaded it in `Backendless hosted custom service` but it's returning me an error when I try to invoke it using the SDK in Swift.

My Library is below:

SalvarContatosLibrary.java

  1. package com.mbaas.service;
  2. import com.backendless.Backendless;
  3. import com.backendless.servercode.IBackendlessService;
  4. import java.util.ArrayList;
  5. public class SalvarContatoLibrary implements IBackendlessService {
  6. public boolean salvarContatos(ArrayList<Contato> contato) {
  7. boolean retorno = true;
  8. if(contatos == null || contatos() == 0) {
  9. retorno = false;
  10. } else {
  11. for(Contato contato: contatos) {
  12. Backendless.Persistence.save(contato);
  13. }
  14. }
  15. return retorno;
  16. }
  17. }

Contato.java

  1. package com.mbaas.service;
  2. import java.util.Date;
  3. /**
  4. * Created by guilhermedupas on 12/07/17.
  5. */
  6. public class Contato {
  7. private Usuario usuario;
  8. private int prioridade;
  9. private String objectId;
  10. private Date created;
  11. private Date updated;
  12. private String ownerId;
  13. }

Usuario.java

  1. package com.mbaas.service;
  2. import java.util.Date;
  3. /**
  4. * Created by guilhermedupas on 12/07/17.
  5. */
  6. public class Usuario {
  7. private String nome;
  8. private String foto;
  9. private Date dataNascimento;
  10. private String numeroTelefone;
  11. private String telefoneE164;
  12. private String objectId;
  13. private Date created;
  14. private Date updated;
  15. private String ownerId;
  16. }

And I am trying to invoke the method as the code below:

Swift Code

  1. func salvarContato() {
  2. let nomeServico = "SalvarContatoLibrary"
  3. let versaoServico = "1.0.0"
  4. let metodoServico = "salvarContatos"
  5. let contatosNSArray = contatos as! NSArray
  6. backendless?.customService.invoke(nomeServico, serviceVersion: versaoServico, method: metodoServico, args: contatosNSArray as! [Any],
  7. response: { (result: Any?) -> Void in
  8. print(result)
  9. }, error: { (fault: Fault?) -> Void in
  10. print("Erro contatos")
  11. print("Server reported an error to save the User: \(fault)")
  12. })
  13. }

The error it's returning is:

`Server reported an error to save the User: Optional(FAULT = '0' [ExceptionClass:"CodeRunnerException" {Msg:"Wrong number of arguments", Cause:"none"}] <ExceptionClass:"CodeRunnerException" {Msg:"Wrong number of arguments", Cause:"none"}> )`

Leave a Comment

Comments (12)

photo
1

is "contatosNSArray" and empty array?

photo
1

No, "contatosNSArray" is not empty.

I tried now casting contatos to NSMutableArray

"contatosNSMutableArray = contatos as! NSMutableArray"

and it stoped retuning me the error but It's returning a response as a number "0" and it is not saving the data.

photo
1

What does contatorNSArray contain? The objects in there must structurally match the classes which are expected on the server.

photo
1

It matches. I have made the jar library to contain the same classes that the app needs.

I will double check it tomorrow morning to certify that everything is Ok.

photo
1

Please post the Swift classes here. Also, do your Java classes have any public get/set methods for the fields?

photo
1

No. It doesn't have any get/set methods. Is it mandatory?

The Swift classes are below:

  1. class Usuario: NSObject, NSCoding {
  2. //MARK: Propriedades
  3. var nome: String?
  4. var foto: String?
  5. var dataNascimento: Date?
  6. var numeroTelefone: String?
  7. var telefoneE164: String?
  8. var objectId: String?
  9. var created: Date?
  10. var updated: Date?
  11. var ownerId: String?
  12. override init() {}
  13. required init(coder aDecoder: NSCoder) {
  14. nome = aDecoder.decodeObject(forKey: "nome") as? String
  15. foto = aDecoder.decodeObject(forKey: "foto") as? String
  16. dataNascimento = aDecoder.decodeObject(forKey: "dataNascimento") as? Date
  17. numeroTelefone = aDecoder.decodeObject(forKey: "numeroTelefone") as? String
  18. telefoneE164 = aDecoder.decodeObject(forKey: "telefoneE164") as? String
  19. objectId = aDecoder.decodeObject(forKey: "objectId") as? String
  20. created = aDecoder.decodeObject(forKey: "created") as? Date
  21. updated = aDecoder.decodeObject(forKey: "updated") as? Date
  22. ownerId = aDecoder.decodeObject(forKey: "ownerId") as? String
  23. }
  24. func encode(with aCoder: NSCoder) {
  25. if let nomeUsuario = nome {
  26. aCoder.encode(nomeUsuario, forKey: "nome")
  27. }
  28. if let fotoUsuario = foto {
  29. aCoder.encode(fotoUsuario, forKey: "foto")
  30. }
  31. if let dataNascimentoUsuario = dataNascimento {
  32. aCoder.encode(dataNascimentoUsuario, forKey: "dataNascimento")
  33. }
  34. if let numeroTelefoneUsuario = numeroTelefone {
  35. aCoder.encode(numeroTelefoneUsuario, forKey: "numeroTelefone")
  36. }
  37. if let telefoneE164Usuario = telefoneE164 {
  38. aCoder.encode(telefoneE164Usuario, forKey: "telefoneE164")
  39. }
  40. if let objectIdUsuario = objectId {
  41. aCoder.encode(objectIdUsuario, forKey: "objectId")
  42. }
  43. if let createdUsuario = created {
  44. aCoder.encode(createdUsuario, forKey: "created")
  45. }
  46. if let updatedUsuario = updated {
  47. aCoder.encode(updatedUsuario, forKey: "updated")
  48. }
  49. if let ownerIdUsuario = ownerId {
  50. aCoder.encode(ownerIdUsuario, forKey: "ownerId")
  51. }
  52. }
  53. }

  1. class Contato: NSObject, NSCoding {
  2. var contatoBackendless: Usuario?
  3. var prioridade: Int?
  4. override init() {}
  5. required init(coder aDecoder: NSCoder) {
  6. contatoBackendless = aDecoder.decodeObject(forKey: "contatoBackendless") as? Usuario
  7. confirmado = aDecoder.decodeObject(forKey: "prioridade") as? Int
  8. }
  9. func encode(with aCoder: NSCoder) {
  10. if let contatoIDoParty = contatoBackendless {
  11. aCoder.encode(contatoIDoParty, forKey: "contatoBackendless")
  12. }
  13. if let prioridadeContato = prioridade {
  14. aCoder.encode(prioridadeContato, forKey: "prioridade")
  15. }
  16. }
  17. }

photo
1

If all the fields are private, no data can be passed using these objects.

If you'd use version 4 of Backendless it automatically generates Swift code for the deployed services:

d44e41da44408f66447cb3d40f29538a

photo
1

I am using version 3 of Backendless and it has the custom SDK to download but when I open the project it shows me some errors.

photo
1

Swift code generation for version 3 does not work correctly.

photo
1

Unless you plan to be on a paid plan on version 3, I recommend switching to version 4.

The free plans on version 3 will be discontinued on November 1st, 2017.

Regards,

Mark

photo
1

Yes, I intend to do it. I just need to solve this question about the hosted custom service to migrate.

photo
1

I would recommend the following approach:

1. Modify your java code so it either declares public fields or get/set methods for the private fields.

2. Create the jar for the service and deploy in the 4.0 app. This is so you can generate the Swift code for it.

3. Once the swift code is generated, use it with your 3.x app.