I am querying the database like below. However, orderbyAscending does not work properly, the accented letters are all sorted at the bottom. Is there any way Parse sorts it by locale? Or do I have to sort in the code? The string array is not long, about 40 words.
var query = PFQuery(className: RFIstanbulDistrictsClassKey)
query.whereKey(RFIstanbulDistrictsDistrictKey, notEqualTo: "")
query.orderByAscending(RFIstanbulDistrictsDistrictKey)
// constants are defined as follows:
// let RFIstanbulDistrictsClassKey = "IstanbulDistricts"
// let RFIstanbulDistrictsDistrictKey = "district"
It turns out I need to sort the array after loading it from Parse:
districts.removeAll(keepCapacity: true)
let query = PFQuery(className: RFIstanbulDistrictsClassKey)
query.whereKey(RFIstanbulDistrictsDistrictKey, notEqualTo: "")
query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if error == nil {
districts = objects.map { String($0[RFIstanbulDistrictsDistrictKey] as! String) }
districts.sort { return $0 < $1 } // sort ascending
}
}
Related
i try to show a array list sorted by its Timestamp in an descending order (newest first --> highest ts first) therefore i created a downloading method and a sorting method:
func getBlogsByAuthor(){
self.allBlogs.removeAll()
for authorId in self.authorIds{
db.collection("Blogs").whereField("authorId", isEqualTo: authorId)
.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let ts = document.get("ts") as! Int
let title = document.get("title") as! String
let body = document.get("body") as! String
let authorId = document.get("authorId") as! String
let state = document.get("stateios") as? String
let imageUrl = document.get("imageUrl") as! String
let id = document.documentID as! String
let blogObject = BlogObject.init(title: title , body: body, imageUrl: imageUrl , authorId: authorId , state: state ?? "Null" , id: id, ts: ts )
self.allBlogs.append(blogObject)
}
self.sortDataset()
}
}
}
}
func sortDataset(){
self.allBlogs.sorted(by: { $0.ts! < $1.ts! })
self.rv.reloadData()
}
The problem is that the values are showing always the lowest ts first no matter if i change it from self.allBlogs.sorted(by: { $0.ts! < $1.ts! })
to self.allBlogs.sorted(by: { $0.ts! > $1.ts! })
You need
self.allBlogs.sort { $0.ts! < $1.ts! } // mutating sort in place
as sorted(by returns a result that you ignore it and don't re-assign it would be
self.allBlogs = self.allBlogs.sorted(by: { $0.ts! < $1.ts! })
I'd like to retrieve only certain columns from Parse. But it downloads the whole objects instead:
let usersQuery = PFQuery(className: "_User")
usersQuery.whereKey("userId", containedIn: self.memberIds!) // Array of Strings containing the userIds
usersQuery.selectKeys(["email"])
usersQuery.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) -> Void in
if error != nil {
print(error)
} else if let users = objects as? [PFUser] {
print("objects: \(users)")
// prints whole object, not only "email" field
}
})
The output:
objects: [<PFUser: 0x7fb1095a7270, objectId: 9Ld9vRPoLZ, localId: (null)> {
email = "iphone5s#mail.com";
fullname = "iPhone 5S";
// ... other fields
}]
I have a column "checkInTime" in my Parse class that is of type Date.
I am trying to query any checkInTimes after a certain time
Here is the code I am using
func reloadCheckInView() {
checkIns.removeAll(keepCapacity: true)
let friendsListQuery = PFQuery(className: "Friends")
friendsListQuery.includeKey("friendId")
friendsListQuery.includeKey("user")
friendsListQuery.whereKey("friendId", equalTo: PFUser.currentUser()!)
friendsListQuery.whereKey("approved", equalTo: true)
friendsListQuery.findObjectsInBackgroundWithBlock {(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
let user = object["user"] as! PFObject
let now = NSDate()
print(now)
let BeforeNow = NSDate().dateByAddingTimeInterval(self.hourWindow * -3600)
print(self.hourWindow)
print(BeforeNow)
let checkInQuery = PFQuery(className: "LocationCheckIn")
checkInQuery.includeKey("user")
checkInQuery.whereKey("CheckInTime", greaterThan: BeforeNow)
checkInQuery.whereKey("user", equalTo: user)
//let subQuery = PFQuery.orQueryWithSubqueries([friendsListQuery, checkInQuery])
checkInQuery.findObjectsInBackgroundWithBlock {(results: [PFObject]?, error: NSError?) -> Void in
if error == nil {
//print(results)
for result in results! {
self.checkIns.append(result)
}
print(self.checkIns)
}
else {
}
}
}
}
else {
print(error)
}
}
}
and my prints which shows the calculations are working as expected..in this case 1 hr before now.
2015-10-17 15:23:49 +0000
1.0
2015-10-17 14:23:49 +0000
[]
and no records found in my query.
If I comment out
checkInQuery.whereKey("CheckInTime", greaterThan: BeforeNow)
the record is printed and you can see the checkIn time should pass my query but doesn't. Any ideas?
[<LocationCheckIn: 0x12903edb0, objectId: M7zTD3qiCL, localId: (null)> {
checkInPlaceId = "ChIJfc7vF8upVogRk20hK-LzaAM";
checkInPlaceName = "12434 Willingdon Rd";
checkInTime = "2015-10-17 14:26:00 +0000";
location = "<PFGeoPoint: 0x127ed52f0, latitude: 35.436804, longitude: -80.828736>";
user = "<PFUser: 0x127ed76d0, objectId: WCMmKTvNUC, localId: (null)>";
}]
And as I just read through my own question I see my error.. a typo
checkInQuery.whereKey("CheckInTime", greaterThan: BeforeNow)
should be
checkInQuery.whereKey("checkInTime", greaterThan: BeforeNow)
How can i get First rows of createdAt for each username?
for example: backend looks like this
objectId- username - photo - createdAt
5135Aer - name1 - image - 2015-08-21
R35AAA - name6 - image - 2015-08-21
G7356W - name3 - image - 2015-08-20
E355B - name1 - image - 2015-08-20
So i want the query will take all rows and skip name1 which is createdAt 2015-08-20 last one because this old row i just want new createdAt rows only for each user.
let query = PFQuery(className: "test")
query.whereKey("receivers", equalTo: PFUser.currentUser()!.username!)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(objects, error) -> Void in
if error == nil {
self.createdAtArray = objects!
print(objects!.count)
I've tried this query but it will take old createdAt and i just want new createdAt for each user , And yes i have set limit to = 1 , but it will show last record not for each user! It just show one result.
So each 20 minutes from now I ask to give the recent object, so if you want query images after 50 minutes or more just change the value for timestamp.
let query = PFQuery(className: "test")
query.whereKey("receivers", equalTo: PFUser.currentUser()!.username!)
query.orderByDescending("createdAt")
var timeStamp = NSDate(timeIntervalSinceNow: -1200)
query.whereKey("createdAt", greaterThanOrEqualTo: timeStamp)
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil
{
if let objects = objects as? [PFObject]
{
for one in objects
{
var Getimage = one["image"] as! PFFile
Getimage.getDataInBackgroundWithBlock({ (data:NSData?, error:NSError?) -> Void in
var image = UIImage(data: data!)
// you have the image now
createdAtArray.addObject(image!)
})
}
}
}
}
Second Option : To get the last object from parse use **getFirstObject method
func secondQuery(arraydetails:NSMutableArray){
var query = PFQuery(className: "")
query.orderByDescending("createdAt")
query.limit = 1
query.getFirstObjectInBackgroundWithBlock { (object:PFObject?, error:NSError?) -> Void in
if error == nil
{
var detail = object?.objectForKey("text") as! String
arraydetails.addObject(detail)
}
}
}
I have an array of AnyObject objects in Swift. Each object has attributes of a restaurant, such as name, type, loc, etc. How can I filter the array if I want to keep all objects in the array that contain type: "Sushi".
Sample array of [AnyObject] with 2 objects. The filter should keep the first object (type: sushi):
[<Restaurant: 0x7ff302c8a4e0, objectId: LA74J92QDA, localId: (null)> {
City = "New York";
Country = "United States";
Name = Sumo Japan;
Type = Sushi, Japanese, Asian;
}, <Restaurant: 0x7ff302daa790, objectId: 0aKFrpKN46, localId: (null)> {
City = "New York";
Country = "United States";
Name = Little Italy;
Type = Italian, Pizza;
}]
Current Code (but I'm not sure if the filter can search through an array of [AnyObject]) :
var query = PFQuery(className:"Restaurant")
query.whereKey("RestaurantLoc", nearGeoPoint:userGeoPoint, withinMiles:50)
query.limit = 2
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if objects != nil {
println("list of objects of nearby")
println(objects)
let searchString = "Sushi"
let predicate = NSPredicate(format: "Type CONTAINS[cd] %#", searchString);
//Line below gives error: '[AnyObject]' does not have a member named 'filteredArrayUsingPredicate'
//let filteredArray = objects.filteredArrayUsingPredicate(predicate!)
Your array, objects, is an array of PFObject objects. Thus, to filter the array, you might do something like:
let filteredArray = objects.filter() {
if let type = ($0 as PFObject)["Type"] as String {
return type.rangeOfString("Sushi") != nil
} else {
return false
}
}
My original answer, based upon an assumption that we were dealing with custom Restaurant objects, is below:
You can use the filter method.
Let's assume Restaurant was defined as follows:
class Restaurant {
var city: String
var name: String
var country: String
var type: [String]!
init (city: String, name: String, country: String, type: [String]!) {
...
}
}
So, assuming that type is an array of strings, you'd do something like:
let filteredArray = objects.filter() {contains(($0 as Restaurant).type, "Sushi")}
If your array of types could be nil, you'd do a conditional unwrapping of it:
let filteredArray = objects.filter() {
if let type = ($0 as Restaurant).type as [String]! {
return contains(type, "Sushi")
} else {
return false
}
}
The particulars will vary a little depending upon your declaration of Restaurant, which you haven't shared with us, but hopefully this illustrates the idea.
Swift 3 Solution
Use the filter method on an array.
let restaurants: [Restaurants] = [...]
restaurants.filter({(restaurant) in
return Bool(restaurant.type == "sushi")
})
or return Bool(restaurant.type.contains("sushi")) if type is an array.
Ok, if the array objects contains only Restaurant(s) the following code does work.
Lets say Restaurant is something like this:
enum RestaurantType {
case Sushi, Japanese, Asian
}
class Restaurant {
var type = [RestaurantType]()
// more properties here...
}
First of all lets define an array of Restaurant(s).
var restaurants = objects as [Restaurant]
Then we can filter it:
var sushiRestaurants = restaurants.filter { (restaurant : Restaurant) -> Bool in
return contains(restaurant.type, .Sushi)
}
Update:
Now I am assuming objects is an array of PFObject(s)
Just ignore my previous code and try this:
var restaurants = objects as [PFObject]
var sushiRestaurants = restaurants.filter { (restaurant : PFObject) -> Bool in
return contains(restaurant["Type"], "Sushi")
}
Maybe it will crash again, the problem is that I don't know the type of Restaurant.Type. I'm trying. Maybe the next error message will provide more useful info.
Modification of Rob's answer as Swift 2.0, In swift 2.0 using Rob's code gives error as follows -
initializer for conditional binding must have optional type, not 'string'
However it can be solved by using guard statement instead of if-let as below -
let filteredArray = objects.filter() {
guard let type = ($0 as PFObject)["Type"] as String else {
return false
}
return type.rangeOfString("Sushi") != nil
}
I have a solution as given below.
func filterByCuisineType(list: [Restaurant]) -> [Restaurant]{
if self.cuisineTypes.count == 0 {
return list
}
let array: [Restaurant] = list.filter { (restaurant) -> Bool in
for cuisineName in self.cuisineTypes{
let isContained: Bool = restaurant.cuisineType.contains(cuisineName)
if isContained {
return true
}
}
return false
}
return array
}