Hi
Strange one this
My app running on swift version 3 was retrieving backendless v5.x data correctly.
I have now updated the app to run on swift 5 and something, somewhere along the way has caused the data not to be found correctly. Maybe the code is not correct for swift 5? Perhaps you can see what may be wrong… Conversion to swift 5 syntax is as far as I am aware the only thing which has changed - no code relating to Backendless should have changed, at least not deliberately!
I can find the data objects correctly…
let dataQuery = DataQueryBuilder()
//using custom class approach
let dataStore = backendless?.data.of(LoyaltyPoints().ofClass())
var response = LoyaltyPoints
Types.tryblock({ () -> Void in
response = dataStore?.find(dataQuery) as! [LoyaltyPoints]
while (response.count != 0){
//successfully finds 69 objects here.
dump(response)
//however each response contains nil data
i.e
<A2.LoyaltyPoints: 0x283fa8b00> #0
super: NSObject**
objectId: nil
user: nil
name: nil
loyaltyPointValue: 0
etc..
dataQuery?.prepareNextPage()
response = dataStore?.find(dataQuery) as! [LoyaltyPoints]
}
},
catchblock: { (exception) -> Void in
// handle error from server here
print("Server reported an error")
})
So it is finding the data objects successfully but there is nothing in there. If I run the same code on Swift V3 it is working correcty so something strange has happened along the way to make all my objects return nil data!
LoyaltyPoints.swift looks like something like this…
import Foundation
class LoyaltyPoints : NSObject {
var objectId : String?
var user: BackendlessUser?
var name : String?
var dateTime: Date?
var created2: Date?
var verified: String?
var loyaltyPointValue: Int = 0
}
Hi @mike-turner,
Make sure to add the @objcMembers
attribute to your data classes. This is per the API doc:
https://backendless.com/docs/ios/data_data_object.html
Regards,
Mark
Perfect. Fixed.
Thanks for putting me right, and apologies for not seeing that!
Mike
Similar problem I think, probably due to to swift conversion as it was working so keeping on same thread.
It seems the async method does not seem to ever get to the response or show an error either. Nothing, but the sync method seems to work so must be something to do with async methods and/or swift4/5 conversion.
let dataStore = self.backendless?.data.of(DeviceInfo().ofClass())
dataStore?.find({
(array) -> () in
let devicesArray = array as! [DeviceInfo]
print("did I find anything!"). // never even gets here
print("Result: \(devicesArray)")
},
error: {
(fault : Fault?) -> () in
print("Server reported an error: \(fault)")
})
My DeviceInfo class
@objcMembers
class DeviceInfo : NSObject {
var objectId: String?
var UUID: String?
var OS : String?
var Version: String?
var AppVersion: String?
var loggedIn : Date? //date
var created: NSDate?
var created2: Date?
var updated: NSDate?
}
Hello mike,
please provide your Application ID.
Regards,
Olha
Hi Olha, here you go
App ID : 49F668C0-314F-EB6F-FF03-8813A8AC1900
apologies was testing with this one: 494D0AFB-19A8-43B5-B82F-9A94126D05AC
Everything works fine for me:
@objcMembers class DeviceInfo: NSObject {
var objectId: String?
var UUID: String?
var OS : String?
var Version: String?
var AppVersion: String?
var loggedIn : Date? //date
var created: NSDate?
var created2: Date?
var updated: NSDate?
}
func test() {
let dataStore = Backendless.sharedInstance().data.of(DeviceInfo().ofClass())
dataStore?.find({ (array) -> () in
let devicesArray = array as! [DeviceInfo]
print("did I find anything!") // never even gets here
print("Result: \(devicesArray)")
}, error: {
(fault : Fault?) -> () in
print("Server reported an error: \(fault)")
})
}
And here is the result:
Please make sure you’ve configured and initialized your app correctly.
Regards,
Olha
Thanks Olha.
This is so frustrating. I know it should work, but it just doesn’t fire
All of my other Backendless functions are working, so I am guessing the app is set up right.
It must be something to do with the async methods and swift 4 changes, but I can’t find it.
Look this method works, there must be some clue here
func test(){
let dataStore = backendless?.data.of(DeviceInfo().ofClass())
let dataQuery = DataQueryBuilder()
var response = [DeviceInfo]()
Types.tryblock({ () -> Void in
// synchronous backendless API call here
response = dataStore?.find(dataQuery) as! [DeviceInfo]
print("I am here") //works!
},
catchblock: { (exception) -> Void in
// handle error from server here
print("Server reported an error")
}) }
ooh I found it, I kind of answered my own question with my clue!
I had it running inside
DispatchQueue.global(qos: .background).async {
...
}
Take it out of that block and it works fine. (used to work fine in swift3, but doesn’t in swift 4/5)
Olha, a bit beyond Backendless support, but what would you advise - just take it out of the background thread as it is an async operation anyway?
Mike
This code also works fine for me:
func test() {
DispatchQueue.global(qos: .background).async {
let dataStore = self.backendless?.data.of(DeviceInfo().ofClass())
dataStore?.find({ (array) -> () in
let devicesArray = array as! [DeviceInfo]
print("did I find anything!") // never even gets here
print("Result: \(devicesArray)")
}, error: {
(fault : Fault?) -> () in
print("Server reported an error: \(fault)")
})
}
}
What version of iOS-SDK do you use?
Got it! - I was using an old version of backendless SDK (4.0b7) in my podfile. Updated to the new one and it now works in. Thanks, problem solved!
DispatchQueue.global(qos: .background).async {}
Hi Olha
Ha, this again!
This time I was trying to call the exact same code but within the NotificationService.swift extension (same file as per your docs about setting up push notifications)
All works except this again. Same project, it just doesn’t fire again. Added objcMembers to data file, up to date SDK
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
var backendless = Backendless.sharedInstance()
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
BackendlessPushHelper.sharedInstance().processMutableContent(request, withContentHandler: contentHandler)
test() //exact same routine
}
Hello mike,
I know it’s a little bit painful but have you tried to debug the NotificationServiceExtension? You won’t see the console logs if you’re not in the debugging mode (I assume you won’t see them while debugging either). What are you going to change in the push notification appearance?
Regards,
Olha
Hi, Yes I am collecting debug information in the NotificationServiceExtension, but it is no help. It just does not fire in the same place as yesterday
//gets here
dataStore?.find({ (array) -> () in
// never gets here
I am actually not trying to change the push notification appearance, but what I am trying to do is to send data back to a table I have in backendless which collects information about how many messages have been received. ie. each time a device gets a notification I get a row added to a table which effectively says a deviceID has received that push message. Therefore we get feedback on the exact number of devices which received the message. That is the theory.
Hello,
Extensions in Xcode are separated from the main target. Please initialize Backendless for your service before calling your method:
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
BackendlessPushHelper.shared.processMutableContent(request: request, contentHandler: contentHandler)
Backendless.shared.hostUrl = SERVER_URL
Backendless.shared.initApp(applicationId: APPLICATION_ID, apiKey: API_KEY)
// call your method here
}
Regards,
Olha
Thanks Olha, confirmed that works.