I am trying to retrieve some data from a backend services data content type. I have been following the guide in the Documentation but i only know swift and not objective c. I am getting an error ( Error Domain=The specified content type was not found. Code=611 "(null)" ) when calling the fetchAll() Method.
func getMessages(){
let dataStore: EVDataStore = EVDataStore.sharedInstance() as! EVDataStore
dataStore.fetchAll(Message.self, block: { (result, error) -> Void in
if(result != nil){
print(result)
}else{
print(error)
}
})
}
Prints:
Error Domain=The specified content type was not found. Code=611 "(null)"
My Mssage class is defined as follows
class Message: EVObject{
var messageText:NSString = ""
var messegeByName:NSString = ""
var messageToUser:NSString = ""
var isRead:Bool = false
}
5 Answers, 1 is accepted
Hello Diego,
- This error is returned by the server that the content type trying to be reached is not existing. This is due to the fact that in Swift the class name will be serialized to myAppName.MyClassName while it should be only MyClassName. To fix this you need to add @objc (MyClassName) before the class MyClassName
- The object properties should be named as the fields as you would like to see them in the database. The code will look like this:
@objc (Message) class Message: EVObject{
var content:NSString = ""
var createdByName:NSString = ""
var to:NSString = ""
var read:Bool = false
}
Note that the structure in the UI portal is entirely for UI purposes and you can create the field names in the database as it is appropriate for your app, no schema will be enforced. The Structure is required only in the case when you need to define a field of type GeoPoint so that the required index is created in the database.
I have made a simple sample using Swift2 with the described class and properties - you can see it here. Just change the Everlive.setApplicationId("your-appId-here") with your own Telerik Platform appId.
In regard to your last question. For example, as specified in the documentation,
the class properties as defined in this way:
@interface Books : EVObject
@property NSString *title;
@property NSString *author;
@property NSDate *publishedAt;
@end
will be serialized to:
{
"Title" : "Book title"
"Author" : "Book author"
"PublishedAt" : "09/09/2013"
}
Let me know if this has worked for you.
Regards,
Martin
Telerik
Thanks for the reply. adding "@objc (Message)" to the class declaration helped as i am now getting the the message objects from the server. however i cant access the attributes of the message when calling
Message.fetchAll {(messages:Array!, error:NSError!) -> Void in
if(error != nil) {
print("Fetch error 1: \(error)")
} else {
print("Fetch result 1: \(messages[0].content)") // messages has no member 'content'
}
}
if i print messages[0] i just get the Messages out as set in the description override method. So how do i access the content of the message?
the fetchAll method returns an Array of objects. Therefore messages[0] is a general object. You may want to convert it to a Message object and thus Xcode will know that there is a property "content".
Message.fetchAll {(messages:Array!, error:NSError!) -> Void in
if(error != nil) {
print("Fetch error 1: \(error)")
} else {
let MessageItem = messages[0] as! (Message)
let MessageContent = MessageItem.content
print("Fetch result 1: \(MessageContent)")
}
}
Make sure you have both the field "Content" in the data items coming from Telerik Backend and the property "content" in the Message class.
Let me know if that helped.
Regards,
Martin
Telerik
Hi Diego,
Yes, you can filter what results to fetch from the content type. This is done by using EVFetchRequest with NSPredicate. Information about filtering can be found here. The code snippets are in Objective-C, so in Swift it will look like:
let dataStore: EVDataStore = EVDataStore.sharedInstance() as! EVDataStore
//Filter item
let request:EVFetchRequest = EVFetchRequest(kindOfClass: Message.self)
let searchText:String = "Text to search"
request.predicate = NSPredicate(format: "Content == %@",searchText) // the name of the field in the database is Content
dataStore.executeFetchRequest(request, block: { (result, error ) -> Void in
if error == nil{
if result?.count > 0 {
let messageItem = result[0] as! Message
let messageContent = messageItem.content
print("Result: \(messageContent)")
}else{
print("No items found")
}
}else{
print("Error: \(error)")
}
})
Besides filtering you can also use:
Have in mind that by default all fields from the content type are returned from the server, but you can also specify which fields to be returned to minimize the bandwidth.
Hope this has helped.Regards,
Martin
Telerik