Limit objects that are returned from a Deployd query in Swift - swift

I'm using Deployd as back-end for my Swift application. This is how I'm querying the JSON data currently. I need to limit the amount of objects that are returned from a query. I'll implement the pagination part myself. I just want to know that how can I embed the below mentioned $limit method in the query. Any advice would be greatly appreciated.
http://docs.deployd.com/docs/collections/reference/querying-collections.html#s-$limit-1416
From Deployd's Docs:
The $limit command allows you to limit the amount of objects that are
returned from a query. This is commonly used for paging, along with
$skip.
// Return the top 10 scores {
$sort: {score: -1},
$limit: 10 }
import Foundation
class ObjectHandler {
var greetings: [initTable] = []
init(filename: String) {
//filter data
let fileP = NSURL(string: "http://localhost:2403/users/me")
let jsonD = NSData(contentsOfURL:fileP!)
let jso = JSON(data: jsonD!, options: NSJSONReadingOptions.AllowFragments, error: nil)
var id = jso["id"]
let filePath = NSURL(string: "http://localhost:2403/postedjob")
let jsonData = NSData(contentsOfURL:filePath!)
let json = JSON(data: jsonData!, options: NSJSONReadingOptions.AllowFragments, error: nil)
for (key: String, subJson: JSON) in json {
var language:String?, link: String?, description:String?, greetingText: String?
for (key1, value:JSON) in subJson {
switch key1 {
case "briefDes": language = value.string
case "skill": link = value.string
case "userId": description = value.string
case "id": greetingText = value.string
default: break
}
}
let greeting = initTable(language: language, link: link, description: description, greetingText: greetingText)
self.greetings.append(greeting)
self.greetings = self.greetings.filter { $0.description == "\(id)"}
}
}
func getGreetingsAsAnyObjects() -> [String: [AnyObject]]{
return [SelectJobConstant.GreetingOBJHandlerSectionKey: greetings.map { $0 as AnyObject }]
} }

So this is how I made it to work :)
Alamofire.request(.GET, "http://localhost:2403/postedjob", parameters: ["$limit": 2, "$sort": ["userId":"-1"]])
.responseJSON { _, _, JSON, _ in
println(JSON)
}

Related

how to pass the API parameter and parameter is in array

How to pass array parameter
Parameter
[
{
"id": 0,
"followerId": 1030,
"followingId": 1033,
"followerName": "string",
"followingName": "string",
"createdDate": "string",
"message": "string"
}
] //how to solve this array
API Function
class func postFollowers(params:[String: Any],success:#escaping([FollowingDataProvider]) -> Void, failure:#escaping (String) -> Void){
var request = RequestObject()
request = Services.servicePostForFollower(param: params)
APIManager.Singleton.sharedInstance.callWebServiceWithRequest(rqst: request, withResponse: { (response) in
if (response?.isValid)!
{
//success()
print(response?.object as! JSON)
success(self.followingJSONarser(responseObject: response?.object as! JSON));
//followingJSONarser(responseObject: response?.object as! JSON)
}
else
{
failure((response?.error?.description)!)
}
}, withError: {
(error) in
failure((error?.description)!)
})
}
Parsing
static func followingJSONarser(responseObject:JSON) -> [FollowingDataProvider]{
var dataProvider = [FollowingDataProvider]()
let jsonDataa = responseObject["data"]
print(jsonDataa)
let newJSON = jsonDataa["data"].arrayValue
print(newJSON)
for item in newJSON{
print(item)
dataProvider.append(FollowingDataProvider(id: item["userId"].intValue, followerId: item["userId"].intValue, followingId: item["followingId"].intValue, followerName: item["userName"].stringValue, followingName: item["followingName"].stringValue, createdDate: item["createdDate"].stringValue, message: item["message"].stringValue))
}
return dataProvider
}`
You can try to combine SwiftyJson with Codable
struct Root: Codable {
let id, followerID, followingID: Int
let followerName, followingName, createdDate, message: String
enum CodingKeys: String, CodingKey {
case id
case followerID = "followerId"
case followingID = "followingId"
case followerName, followingName, createdDate, message
}
}
if let con = response?.object as? JSON {
do {
let itemData = try con.rawData()
let res = try JSONDecoder().decode([Root].self, from: itemData)
print(res)
catch {
print(error)
}
}
Also avoid force-unwraps with json
response?.object as! JSON
Following your code you're trying to parse data from API, you can use SwiftyJSON with Alamofire to create an HTTP request (post,get,put,delete,etc)
You should use arrayObject instead of arrayValue
Your code missing the right definition to data parsing
static func followingJSONarser(responseObject:JSON) -> [FollowingDataProvider]{
var dataProvider = [FollowingDataProvider]()
var itemClass = [ItemClass]()
let jsonDataa = responseObject["data"] as! Dictionary
let newJSON = jsonDataa["data"].arrayObject as! Array
Now create a dataModel class to cast data to it
class ItemsClass:NSObject{
var id:Int = 0
var followerId:Int = 0
var followingId:Int = 0
var followerName:String = ""
var followingName:String = ""
var createdDate:String = ""
var message:String = ""
init(data:JSON) {
self.id = data["userId"].intValue
self.followerId = data["userId"].intValue
self.followingId = data["followingId"].intValue
self.followerName = data["userName"].stringValue
self.followingName = data["followingName"].stringValue
self.createdDate = data["createdDate"].stringValue
self.message = data["message"].stringValue
}
}
for item in newJSON{
dataProvider.append(itemClass)
}
return dataProvider
}`

How to sort JSON Data in Array in swift 4

I have JSON array like this
var json = NSArray() // array with json objects
//print json >>
json = (
{
Name = "Alen";
Score = 500;
},
{
Name = "John";
Score = 0;
},
{
Name = "Mark";
Score = 2000;
},
{
Name = "Steve";
Score = 300;
},
{
Name = "Ricky";
Score = 900;
}
)
and i can access its objects as
(json[0] as! NSDictionary).object(forKey: "Name")
(json[0] as! NSDictionary).object(forKey: "Score")
I want to sort this JSON array according to scores.
I found the answers like
let sortedArray = json.sorted(by: { $0.0 < $1.0 })
which gives error
Value of type 'Any' has no member '0'
Then I tried this
let sortedArray = (json as! NSDictionary).sorted {(aDic, bDic) -> Bool in
return aDic.key < bDic.key
}
It gave error
Binary operator '<' cannot be applied to two 'Any' operands
Can you please guide me to sort the array according to score in swift 4?
That's a very good example why you are strongly discouraged from using NSArray and NSDictionary in Swift.
Both collection types don't provide type information so everything is treated as Any. Most of the shared generic API of the Swift Standard library cannot be used with Any so you are not able to take advantage of the powerful generic functions unless you add a lot of ugly type casts.
If all values are String declare your array as
var json = [[String:String]]()
Then you can sort the array with
let sortedArray = json.sorted { $0["Score"]! < $1["Score"]! }
The most recommended solution is to decode the JSON directly into a custom struct
struct Player : Decodable {
let name : String
let score : String
private enum CodingKeys : String, CodingKey { case name = "Name", score = "Score" }
}
Then you get rid of all type casting and you can sort by the property name
var players = [Player]()
let jsonString = """
[{"Name" : "Alen", "Score" : "500"},
{"Name" : "John", "Score" : "0"},
{"Name" : "Mark", "Score" : "2000"},
{"Name" : "Steve", "Score" : "300"},
{"Name" : "Ricky", "Score" : "900"}]
"""
let data = Data(jsonString.utf8)
do {
players = try JSONDecoder().decode([Player].self, from: data)
let sortedPlayers = players.sorted{ $0.score.compare($1.score, options: .numeric) == .orderedAscending }
print(sortedPlayers)
} catch { print(error) }
Edit:
To load the JSON use an asynchronous way (URLSession)
Never load data from a remote URL with synchronous Data(contentsOf.
var players = [Player]()
let jsonUrl = URL(string: "url.json")!
let task = URLSession.shared.dataTask(with : url) { [unowned self] (data, _, error) in
if let error = error { print(error); return }
do {
players = try JSONDecoder().decode([Player].self, from: data!).sorted{ $0.score < $1.score }
DispatchQueue.main.async { // reload the table view if necessary
self.tableView.reloadData()
}
} catch { print(error) }
}
task.resume()
After parsing your json, you can sort your score array like this
var scoreArray = ["500", "0", "2000", "300", "900"]
array.sort { $0.compare($1, options: .numeric) == .orderedAscending }
I did something like this before
First I created two arrays of dictionary
var jsonArray = [(name:String, score:String)]()
var sortedscoreArray:[(name: String, score: String)] = []
and in getting json data you can create for loop
for I in 0..< jsonData.count{
Let jsonInfo = jsonData[i]
jsonArray.append((name: jsonInfo[“Name”].string!, score: jsonInfo[“Score"].string!))
}
and after you fill the json array pass it to sortedArray
sortedscoreArray = jsonArray.sorted(by: { $0.score < $1.score })
If array contains dictionary then you can use this code for sorting:
let sortedArray = json.sort { $0["Score"] as! Int < $1["Score"] as! Int }
print(sortedArray)
and if you are using bean class then you can use dot(.) properties for sorting:
let sortedArray = json.sort { $0.Score < $1.Score }
print(sortedArray)
let sortedResults = self.json?.sorted(by: {$0.name ?? EMPTY_STRING < $1.name ?? EMPTY_STRING }) ?? []

Multiple Realm objects to JSON

I am trying to convert Realm Object into JSON. My version is working but not if you want to put multiple objects into JSON. So my question is, how should you add multiple Realm Objects into JSON?
Something like that:
{
"Users": [
{"id": "1","name": "John"},{"id": "2","name": "John2"},{"id": "3","name": "John3"}
],
"Posts": [
{"id": "1","title": "hey"},{"id": "2","title": "hey2"},{"id": "3","title": "hey3"}
]
}
This is what I am doing right now:
func getRealmJSON(name: String, realmObject: Object, realmType: Any) -> String {
do {
let realm = try Realm()
let table = realm.objects(realmType as! Object.Type)
if table.count == 0 {return "Empty Table"}
let mirrored_object = Mirror(reflecting: realmObject)
var properties = [String]()
for (_, attr) in mirrored_object.children.enumerated() {
if let property_name = attr.label as String! {
properties.append(property_name)
}
}
var jsonObject = "{\"\(name)\": ["
for i in 1...table.count {
var str = "{"
var insideStr = String()
for property in properties {
let filteredTable = table.value(forKey: property) as! [Any]
insideStr += "\"\(property)\": \"\(filteredTable[i - 1])\","
}
let index = insideStr.characters.index(insideStr.startIndex, offsetBy: (insideStr.count - 2))
insideStr = String(insideStr[...index])
str += "\(insideStr)},"
jsonObject.append(str)
}
let index = jsonObject.characters.index(jsonObject.startIndex, offsetBy: (jsonObject.count - 2))
jsonObject = "\(String(jsonObject[...index]))]}"
return jsonObject
}catch let error { print("\(error)") }
return "Problem reading Realm"
}
Above function does like that, which is good for only one object:
{"Users": [{"id": "1","name": "John"},{"id": "2","name": "John2"},{"id": "3","name": "John3"}]}
Like this I call it out:
let users = getRealmJSON(name: "Users", realmObject: Users(), realmType: Users.self)
let posts = getRealmJSON(name: "Posts", realmObject: Posts(), realmType: Posts.self)
And I tried to attach them.
Can anybody please lead me to the right track?
You can use data models to encode/decode your db data:
For example you have
class UserEntity: Object {
#objc dynamic var id: String = ""
#objc dynamic var createdAt: Date = Date()
#objc private dynamic var addressEntities = List<AddressEntity>()
var addresses: [Address] {
get {
return addressEntities.map { Address(entity: $0) }
}
set {
addressEntities.removeAll()
let newEntities = newValue.map { AddressEntity(address: $0) }
addressEntities.append(objectsIn: newEntities)
}
}
}
Here you hide addressEntities with private and declare addresses var with Address struct type to map entities into proper values;
And then use
struct User: Codable {
let id: String
let createdAt: Date
let addresses: [Address]
}
And then encode User struct any way you want

how to deserialize a collection from an alamofire request

this is a pretty basic question of the syntax for deserializing responsejson collection in alamofire and swift
I have a GET service that returns an array of user objects e.g.
[
{"uname": "bob"},
{"uname": "jane"}
]
and here is my request
Alamofire.request(.GET, url , encoding:.JSON)
.responseJSON(options: .MutableContainers, completionHandler:{ (request, response, JSON, error) -> Void in
let result = JSON as? [Dictionary<String,String>]
if (response!.statusCode == 200 && error == nil){
//how should I deserialize the result here to return [String]
callback(success: true, errorMsg: nil, friends:friends)
}
else{
callback(success: false,errorMsg:error?.localizedDescription,friends:nil)
}
})
My question is how to deserialize the result, and am I correct to assume that the json result is a [Dictionary] and in order for me to change it to a [String] result, should I map it?
If I use the map syntax below I have a few questions
let friends = result?.map {
return $0["uname"] as String?
}
With the optional return value can I get it to return a [String] instead of a [String?] in a graceful way - isn't there a way to let map return only non null values somehow in a concise syntax?
Also is there a better syntax for map that lets me name the parameters instead of using $0?
I use Alamofire with SwiftyJSON to do the job and deserialise array of JSON objects to native objects. Here is an example of how I do it:
Alamofire.request(request)
.responseJSON(options: nil) { (request, response, json, error) -> Void in
if let requestError = error as NSError?{
callback!(nil, nil, requestError)
}
if let httpResponse = response as NSHTTPURLResponse?{
if(httpResponse.statusCode != 200){
callback!(nil, httpResponse, nil)
} else{
let jsonResult = JSON(json!) as JSON
var concerts = self.deserializeConcerts(jsonResult)
callback!(concerts, nil, nil)
}
}
}
Deserialize concerts looks like this:
class private func deserializeConcerts(concerts: SwiftyJSON.JSON) -> [ConcertModel]{
let concertsArray = concerts.object as! NSMutableArray
var concertObjs = [ConcertModel]()
for concert in concertsArray{
let concertObj = ConcertModel(concert: concert as! NSDictionary)
concertObjs.append(concertObj)
}
return concertObjs
}
And finally, ConcertModel initialiser just maps the values of the NSDictionary to the properties of the ConcertModel object.
Updated implementation for Alamofire 4.3
Alamofire.request(url, method: .get)
.responseJSON { response in
if response.data != nil {
let json = JSON(data: response.data!)
let name = json["data"][0]["name"].string
if name != nil {
print(name!)
}
}
}
That will parse this JSON input:
{
data: [
{ name: 'John' },
{ name: 'Dave' }
]
}

How to use swiftyjson to parse json data to foundation object and loop through data

So I'm trying to get his raw json data and use it to ultimately be viewed in a table(so one table cell would be --> Emirates - $1588.77)
Problem: Having trouble parsing the JSON data.. alamofire apparently does it automatically? but im completely confused with the data types. I keep getting weird errors like 'doesnt have a member named subscript" (I've also got swiftyjson installed but aa non-swiftyjson solution should work as well.
Code:
request(qpxRequest).responseJSON { (request, response, json, error) -> Void in
if response != nil {
//println(response!)
}
if json != nil {
// 1. parse the JSON data into a Foundation object
// 2. Grab the data from the foundation object (so its can be looped though in a table)
}
{
trips = {
data = {
carrier = (
{
name = "Cathay Pacific Airways Ltd.";
},
{
name = Emirates;
},
{
name = "Ethiopian Airlines Enterprise";
},
{
name = "Qantas Airways Ltd.";
},
{
name = "South African Airways";
}
);
};
tripOption = (
{
saleTotal = "AUD1537.22";
},
{
saleTotal = "AUD1588.77";
},
{
saleTotal = "AUD1857.42";
},
{
saleTotal = "AUD1857.42";
},
{
saleTotal = "AUD1922.42";
}
);
};
}
-------- Edit.
Using this model.
class FlightDataModel {
var carrier: String
var price: String
init(carrier: String?, price: String?) {
self.carrier = carrier!
self.price = price!
}
}
How woudl I use your solution to add it to an array of FlightDataModel class
This my my attempt..
var arrayOfFlights : [FlightDataModel] = [FlightDataModel]()
if let tripOptions = trips["tripOption"] as? [[String:AnyObject]] {
for (index, tripOption) in enumerate(tripOptions) {
//println("\(index): " + (tripOption["saleTotal"]! as String))
self.arrayOfFlights[index].carrier = tripOption["saleTotal"]! as String
println("\(self.arrayOfFlights[index].carrier)")
}
Alamofire can do it, but you have to dig into your JSON structure. :)
Like this, using Alamofire's responseJSON method:
Alamofire.request(.GET, YOUR_URL, parameters: nil, encoding: .URL).responseJSON(options: NSJSONReadingOptions.allZeros) { (request, response, json, error) -> Void in
if let myJSON = json as? [String:AnyObject] {
if let trips = myJSON["trips"] as? [String:AnyObject] {
if let data = trips["data"] as? [String:AnyObject] {
if let carriers = data["carrier"] as? [[String:String]] {
for (index, carrierName) in enumerate(carriers) {
println("\(index): " + carrierName["name"]!)
}
}
}
if let tripOptions = trips["tripOption"] as? [[String:AnyObject]] {
for (index, tripOption) in enumerate(tripOptions) {
println("\(index): " + (tripOption["saleTotal"]! as! String))
}
}
}
}
}
Output:
0: Cathay Pacific Airways Ltd.
1: Emirates
...
0: AUD1537.22
1: AUD1588.77
...
It's a bit easier with SwiftyJSON indeed. And for diversity's sake, we'll use Alamofire's responseString method this time:
Alamofire.request(.GET, YOUR_URL, parameters: nil, encoding: .URL).responseString(encoding: NSUTF8StringEncoding, completionHandler: {(request: NSURLRequest, response: NSHTTPURLResponse?, responseBody: String?, error: NSError?) -> Void in
if let dataFromString = responseBody!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
let json = JSON(data: dataFromString)
let carriers = json["trips"]["data"]["carrier"].array
for (index, carrier) in enumerate(carriers!) {
println("\(index):" + carrier["name"].string!)
}
let tripOption = json["trips"]["tripOption"].array
for (index, option) in enumerate(tripOption!) {
println("\(index):" + option["saleTotal"].string!)
}
}
})
Output:
0: Cathay Pacific Airways Ltd.
1: Emirates
...
0: AUD1537.22
1: AUD1588.77
...
Note: I've used enumerate as an example for how getting the index of the content at the same time you get the content.