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
package com.mbaas.service;
import com.backendless.Backendless;
import com.backendless.servercode.IBackendlessService;
import java.util.ArrayList;
public class SalvarContatoLibrary implements IBackendlessService {
public boolean salvarContatos(ArrayList<Contato> contato) {
boolean retorno = true;
if(contatos == null || contatos() == 0) {
retorno = false;
} else {
for(Contato contato: contatos) {
Backendless.Persistence.save(contato);
}
}
return retorno;
}
}
Contato.java
package com.mbaas.service;
import java.util.Date;
/**
* Created by guilhermedupas on 12/07/17.
*/
public class Contato {
private Usuario usuario;
private int prioridade;
private String objectId;
private Date created;
private Date updated;
private String ownerId;
}
Usuario.java
package com.mbaas.service;
import java.util.Date;
/**
* Created by guilhermedupas on 12/07/17.
*/
public class Usuario {
private String nome;
private String foto;
private Date dataNascimento;
private String numeroTelefone;
private String telefoneE164;
private String objectId;
private Date created;
private Date updated;
private String ownerId;
}
And I am trying to invoke the method as the code below:
Swift Code
func salvarContato() {
let nomeServico = "SalvarContatoLibrary"
let versaoServico = "1.0.0"
let metodoServico = "salvarContatos"
let contatosNSArray = contatos as! NSArray
backendless?.customService.invoke(nomeServico, serviceVersion: versaoServico, method: metodoServico, args: contatosNSArray as! [Any],
response: { (result: Any?) -> Void in
print(result)
}, error: { (fault: Fault?) -> Void in
print("Erro contatos")
print("Server reported an error to save the User: \(fault)")
})
}
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"}> )
is “contatosNSArray” and empty array?
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.
What does contatorNSArray contain? The objects in there must structurally match the classes which are expected on the server.
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.
Please post the Swift classes here. Also, do your Java classes have any public get/set methods for the fields?
No. It doesn’t have any get/set methods. Is it mandatory?
The Swift classes are below:
class Usuario: NSObject, NSCoding {
//MARK: Propriedades
var nome: String?
var foto: String?
var dataNascimento: Date?
var numeroTelefone: String?
var telefoneE164: String?
var objectId: String?
var created: Date?
var updated: Date?
var ownerId: String?
override init() {}
required init(coder aDecoder: NSCoder) {
nome = aDecoder.decodeObject(forKey: "nome") as? String
foto = aDecoder.decodeObject(forKey: "foto") as? String
dataNascimento = aDecoder.decodeObject(forKey: "dataNascimento") as? Date
numeroTelefone = aDecoder.decodeObject(forKey: "numeroTelefone") as? String
telefoneE164 = aDecoder.decodeObject(forKey: "telefoneE164") as? String
objectId = aDecoder.decodeObject(forKey: "objectId") as? String
created = aDecoder.decodeObject(forKey: "created") as? Date
updated = aDecoder.decodeObject(forKey: "updated") as? Date
ownerId = aDecoder.decodeObject(forKey: "ownerId") as? String
}
func encode(with aCoder: NSCoder) {
if let nomeUsuario = nome {
aCoder.encode(nomeUsuario, forKey: "nome")
}
if let fotoUsuario = foto {
aCoder.encode(fotoUsuario, forKey: "foto")
}
if let dataNascimentoUsuario = dataNascimento {
aCoder.encode(dataNascimentoUsuario, forKey: "dataNascimento")
}
if let numeroTelefoneUsuario = numeroTelefone {
aCoder.encode(numeroTelefoneUsuario, forKey: "numeroTelefone")
}
if let telefoneE164Usuario = telefoneE164 {
aCoder.encode(telefoneE164Usuario, forKey: "telefoneE164")
}
if let objectIdUsuario = objectId {
aCoder.encode(objectIdUsuario, forKey: "objectId")
}
if let createdUsuario = created {
aCoder.encode(createdUsuario, forKey: "created")
}
if let updatedUsuario = updated {
aCoder.encode(updatedUsuario, forKey: "updated")
}
if let ownerIdUsuario = ownerId {
aCoder.encode(ownerIdUsuario, forKey: "ownerId")
}
}
}
class Contato: NSObject, NSCoding {
var contatoBackendless: Usuario?
var prioridade: Int?
override init() {}
required init(coder aDecoder: NSCoder) {
contatoBackendless = aDecoder.decodeObject(forKey: "contatoBackendless") as? Usuario
confirmado = aDecoder.decodeObject(forKey: "prioridade") as? Int
}
func encode(with aCoder: NSCoder) {
if let contatoIDoParty = contatoBackendless {
aCoder.encode(contatoIDoParty, forKey: "contatoBackendless")
}
if let prioridadeContato = prioridade {
aCoder.encode(prioridadeContato, forKey: "prioridade")
}
}
}
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:
http://support.backendless.com/public/attachments/d44e41da44408f66447cb3d40f29538a.jpg</img>
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.
Swift code generation for version 3 does not work correctly.
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
Yes, I intend to do it. I just need to solve this question about the hosted custom service to migrate.
I would recommend the following approach:
- Modify your java code so it either declares public fields or get/set methods for the private fields.
- Create the jar for the service and deploy in the 4.0 app. This is so you can generate the Swift code for it.
- Once the swift code is generated, use it with your 3.x app.