PFQuery, hasCachedResult() always retuning false? - ios

Currently trying to just check if the query has cached inside PFQueryTableViewcontroller, using a simple if statement but regardless it keeps returning false, even when i turn internet off and can access page through cache.
var query = PFQuery(className: "Tasks")
var isInCache:Bool = query.hasCachedResult()
println(isInCache)
query.cachePolicy = PFCachePolicy.CacheElseNetwork
return query
Trying to just simply us an if statement checking internet and and if there is a cache. If anyone has any workarounds this would be really helpful been on this a while now

Related

Is there a way to pull the last CoreData Entry only?

I have a dashboard view that I'd like to display a few variables from my last entered CoreData entry. However, I can't figure out how to fetch only the last data entered into a variable so I can display it. Any ideas?
EDIT: I'm trying to setup a NSFetchRequest inside of a called function that is called only onappear. However, I'm getting errors and am lost.
func singleEntryPull() -> [Item] {
let request: NSFetchRequest<Item> = Item.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "todaysDate", ascending: false)]
request.fetchLimit = 1
let singleEntry = FetchRequest(fetchRequest: request)
return singleEntry
}
And then the return from the function should only show 1 result and I can then use the returned value to display the variables I need?
Well, not sure if this is the cleanest or best way to do this but I got it working like I want for now until a better solution comes up. I'm still using #FetchRequest which im now aware is pulling data live and updating it, but that might work as if someone keeps the app open overnight and updates it in the morning, I'd want it to display that latest entry. I used this:
ForEach(singleEntry.prefix(1)) { item in
A fetch limit of 1 on a fetch request will return you a single value. However, when you're setting up a #FetchRequest, you're doing more than this - you're making the initial fetch and then continuing to monitor the context for changes, so it live updates. This monitoring only uses the predicate of your fetch request.
Depending on your order of operations, you could be seeing the latest data, and then any new data inserted since you started that view. My experiments with the SwiftUI core data template project prove this out - on initial run you get the a single latest entry, but as you add newer ones, the fetch-limited screen picks up the new entries.
Depending on how this view is actually used, you have two choices - you can do an actual fetch request on appear of the view and store the result as an observable object, or you can make sure you only ever use the first record from the fetch request's results array, which will always be the latest record because of your sort ordering:
var body: some View {
if let latest = singleEntry.first {
// Some view describing the latest entry
} else {
Text("No record")
}
}

How do I create a lazy property without getting errors?

Trying to get the hang of creating lazy class properties. Sometimes it works, other times I get errors and I'm not sure I understand when it's okey to do it and when its not. For example, I created this:
lazy var backgroundContext: NSManagedObjectContext = {
return self.persistentContainer.newBackgroundContext()
}()
Works wonders with no errors. Then I tried one that fetches core data:
lazy var fetchCoreData: [LocalDoorCoreDataObject] = { return coreDataHandler.fetchAll(fetchRequest: NSFetchRequest<LocalDoorCoreDataObject>(entityName: "LocalDoorCoreDataObject") }()
As far as I can see I use the exact same format, but I still get an error
Expected , seperator
and
Expected expression in list expressions
I gues there is some reason I'm not allowed to do it with the core dataproperty, but I'm not sure what. What am I missing?

observeSingleEvent with queryEqual to value doesn't work

So, I want to check if user's device is in my list (for testing). For this I have a small set of values in my Firebase dataset.
It looks like that:
But when I'm trying to check if the user's id is in this list, I'm getting nothing.
let childString = "tempfreeuuid/"
let pointref = ref.child(childString)
let query = pointref.queryOrderedByKey().queryEqual(toValue: "FFFFF")
query.observeSingleEvent(of: DataEventType.value) { (snapshot) in
if snapshot.hasChildren() {
print("that's good")
} else {
print("snapshot has no children")
}
}
And the result is "snapshot has no children".
I've already tried query.observeSingleEvent(of: .childAdded) (doesn't work), .queryLimited(toFirst: 3), and .queryOrderedByKey() — these two don't work either.
At the same time this query is working if I'm not trying to use queryEqual.
What am I doing wrong?
update: I want to clarify the problem I have. I don't have any results, snapshot is null. At the same time if I'm using queryLimited(toFirst: 1) instead of queryEqual, I'm getting one result from the table to work with. It seems to me it's not about snapshot issues, it's about query without any results.
You are using the wrong OrderedBy method. Because you are using queryOrderedByKey the queryEqual function will check if its equal to the Key while you want to compare it to the Value.
Instead you should be using queryOrderedByChild or queryOrderedByValue to make sure you compare the right values.
Here is the reference to the firebase docs explaining how queries (specificly queryEqualToValue in your case) work.

GMSPlacesClient cancel request

In one of my apps users have an ability to search for a location by its name. I am using Google Maps APIs to display autocompleted suggestions with the help of GMSPlacesClient.
Code below illustrates how I do this:
func performSearch() {
let filter = GMSAutocompleteFilter()
filter.type = GMSPlacesAutocompleteTypeFilter.City
placesClient?.autocompleteQuery(searchBar.text!, bounds: nil, filter: filter, callback: { (results, error: NSError?) -> Void in
// update results
})
}
This code works very well. However, I noticed one scenario in which it sort of fails. One example is if I search for "Chicago". If I type "Ch" very fast sometimes the results are returned for "Ch" correctly, but sometimes I obtain the results for "C". The problem arises because these are asynchronous requests and I am performing the search each time user types something. So, even though the request for "C" was initiated before "Ch" it can return last.
I therefore need to cancel all previous initiated requests before I start a new one. However, I couldn't find a way of doing this. Does anyone know how to achieve it?
Update
I have tried to use a workaround:
let string = myResults[0].attributedFullText
string.enumerateAttribute(kGMSAutocompleteMatchAttribute, inRange: NSMakeRange(0, string.length), options: .Reverse) { (value, range, stop) -> Void in
if value != nil {
let t = NSString(string: string.string)
let str = t.substringWithRange(range)
//now compare with original search string
}
}
This fixes the issue with Chicago (and other similar cases). However, such approach will disable autocomplete suggestions when user makes a typo because the matched string and original search string are always different in this case.
So, the question still remains open. An ideal approach would be to cancel all previously initiated requests. If Google also stored the initial search string an approach similar to that presented above could work, but it looks like the original search string is not returned after request...
It seems like the only option is to not use the SDK but to use Alamofire to send requests. Those requests can then be easily cancelled. However, I am not sure how good this is...

Parse with Swift - User Queries

Im trying to query my Parse User database in order to create a friend request between two users. The user inputs a user name that they want to add as a friend. However, when I try to query the database, I get a "EXC_BAD_ACCESS" error on the line where I am adding the condition. Not sure why Im getting this error, as its my understanding it has to do with trying to access memory already freed. Anything that you can do to help would be very appreciated!
var friendship = PFObject(className: "Friends")
var findUser:PFQuery = PFUser.query()
findUser.whereKey("username",equalTo:username2) //program crashes here for some reason
findUser.getFirstObjectInBackgroundWithBlock {
(user2, error: NSError!) -> Void in
if user2 == nil {
println("Failure")
} else {
println("Successfully retrieved the object.")
friendship["user1"] = PFUser.currentUser().objectId
friendship["user2"] = user2.objectId
friendship["pending"] = true
friendship.save()
}
}
Set a breakpoint in the compiler and navigate the steps until you hit the crash so you can understand exactly at which point it crashes a troubleshoot further from there with the better understanding.
Also once it has crashed use LLDB print out po ivar to check if any of your ivars got instantiated and which ones are empty or execute dubious functions with exp func.
So... It works today. Not sure what happened. Co-Developer and I reorganized frameworks and everything works fine now. Thank you for your help everyone. I appreciate the responses :)

Resources