POST request in Alamofire swift 4 - ios

am unable to make nested dict, please help me out
{
"OneStopFlight" : "false",
"TokenId" : "86839fb9-ed93-46d3-b480-c58dbc441838",
"AdultCount" : "1",
"InfantCount" : "0",
"JourneyType" : "1",
"EndUserIp" : "192.168.10.10",
"DirectFlight" : "false",
"Segments" : [
{
"PreferredDepartureTime" : "2018-06-27T00:00:00",
"Origin" : "PNQ",
"EndUserIp" : "192.168.10.10",
"Destination" : "VNS",
"FlightCabinClass" : "1"
}
],
"ChildCount" : "0"
}

If you want to create such dictionary as did showed above , you can create it easily as below
let segmentDict : [[String:Any]] = [
[
"PreferredDepartureTime" : "2018-06-27T00:00:00",
"Origin" : "PNQ",
"EndUserIp" : "192.168.10.10",
"Destination" : "VNS",
"FlightCabinClass" : "1"
]
]
let paramDict : [String:Any] = [
"OneStopFlight" : "false",
"TokenId" : "86839fb9-ed93-46d3-b480-c58dbc441838",
"AdultCount" : "1",
"InfantCount" : "0",
"JourneyType" : "1",
"EndUserIp" : "192.168.10.10",
"DirectFlight" : "false",
"Segments" : segmentDict,
"ChildCount" : "0"
]
let segmentWithMultipleDict : [[String:Any]] = [
[
"PreferredDepartureTime" : "2018-06-27T00:00:00",
"Origin" : "PNQ",
"EndUserIp" : "192.168.10.10",
"Destination" : "VNS",
"FlightCabinClass" : "1"
],
[
"PreferredDepartureTime" : "2018-06-27T00:00:00",
"Origin" : "PNQ",
"EndUserIp" : "192.168.10.10",
"Destination" : "VNS",
"FlightCabinClass" : "1"
]
]
In case if you want to Deque such data
struct dequeResponse
{
var OneStopFlight : String = ""
var TokenId : String = ""
var AdultCount : String = ""
var InfantCount : String = ""
var JourneyType : String = ""
var EndUserIp : String = ""
var DirectFlight : String = ""
var Segments : [segment] = []
var ChildCount : String = ""
func getDataFromJSON(_ data: [String:Any]) -> dequeResponse{
var myResponseValues = dequeResponse()
if let value = data["OneStopFlight"] as? String {
myResponseValues.OneStopFlight = value
}
if let value = data["TokenId"] as? String {
myResponseValues.TokenId = value
}
if let value = data["AdultCount"] as? String {
myResponseValues.AdultCount = value
}
if let value = data["InfantCount"] as? String {
myResponseValues.InfantCount = value
}
if let value = data["JourneyType"] as? String {
myResponseValues.JourneyType = value
}
if let value = data["EndUserIp"] as? String {
myResponseValues.EndUserIp = value
}
if let value = data["DirectFlight"] as? String {
myResponseValues.DirectFlight = value
}
if let value = data["Segments"] as? [[String:Any]] {
let newSegment = segment()
myResponseValues.Segments = newSegment.getDataFromJSON(value)
}
if let value = data["ChildCount"] as? String {
myResponseValues.ChildCount = value
}
return myResponseValues
}
}
struct segment {
var PreferredDepartureTime : String?
var Origin : String?
var EndUserIp : String?
var Destination : String?
var FlightCabinClass : String?
func getDataFromJSON(_ data: [[String:Any]]) -> [segment] {
var segmentAray = [segment]()
for i in 0..<data.count {
var myCurrentSegment = segment()
if let value = data[i]["PreferredDepartureTime"] as? String {
myCurrentSegment.PreferredDepartureTime = value
}
if let value = data[i]["Origin"] as? String {
myCurrentSegment.Origin = value
}
if let value = data[i]["EndUserIp"] as? String {
myCurrentSegment.EndUserIp = value
}
if let value = data[i]["Destination"] as? String {
myCurrentSegment.Destination = value
}
if let value = data[i]["FlightCabinClass"] as? String {
myCurrentSegment.FlightCabinClass = value
}
segmentAray.append(myCurrentSegment)
}
return segmentAray
}
}
Usage
var jsonObject = dequeResponse()
jsonObject = jsonObject.getDataFromJSON(paramDict)
print(jsonObject.Segments)
Note If this doesn't meet your requirement please edit question with more detail

Related

Swift Retrieve Data with Nested Array

I am trying to pass data into variable by displaying it(NameList and BasketDetail). But the basket data is empty(BasketDetail). How can i solve this (Output:Retrieve data: [“name”: Mike, “basket”: <__NSArray0 0x28112c060()])?
Firebase node;
"Pro_" : {
"-MsVcfY7pZI74r0E1ULD" : {
"basket" : {
"-Mruf-UdXxpLK0l8Qgw4" : {
"cat" : "Tech",
"info" : "iOS",
"orderid" : "Ref_1",
},
"-MszuLj3cxm_gE9m-VPO" : {
"cat" : "Tech",
"info" : "Android",
"orderid" : "Ref_2",
}
},
"name" : "-Mike",
}
}
My function;
private func populateNameLists() {
ref = Database.database().reference()
self.ref.child(“Pro_”).observeSingleEvent(of:.value) { (snapshot) in
self.nameLists.removeAll()
let nameListDictionary = snapshot.value as? [String:Any] ?? [:]
for (key,_) in nameListDictionary {
if let nameListDictionary = nameListDictionary[key] as? [String:Any] {
if let nameList = NameList(nameListDictionary) {
self.nameLists.append(nameList)
print(“Retrieve data:”, try! nameList.toDictionary())
}}}}}
Output(Basket's empty ???)
Retrieve data: [“name”: Mike, “basket”: <__NSArray0 0x28112c060()]
Name List
typealias JSONDictionary = [String:Any]
class NameList : Codable {
var basket :[BasketDetail] = [BasketDetail]()
var name: String!
init(name:String ) {
self.name = name
}
init?(_ dictionary :[String:Any]) {
guard let name = dictionary[“name”] as? String else {
return nil
self.name = name
let basketItemsDictionary = dictionary[“basket”] as? [JSONDictionary]
if let dictionaries = basketItemsDictionary {
self.basket = dictionaries.compactMap(BasketDetail.init)
}}}
Basket Detail
class BasketDetail : Codable{
var cat : String
var info : String
var orderid : String
init(cat :String, info :String, orderid :String) {
self.cat = cat
self.info = info
self.orderid = orderid
}
init?(dictionary :JSONDictionary) {
guard let cat = dictionary["cat"] as? String else {
return nil
}
guard let info = dictionary["info"] as? String else {
return nil
}
guard let orderid = dictionary["orderid"] as? String else {
return nil
}
self.cat = cat
self.info = info
self.orderid = orderid
}}

how to map the data which has array of data

My response is :
[
{
"menu_code" : "NDS",
"items" : [
{
"unit" : "Nos",
"name" : "Chapathi\/Pulkas",
"quantity" : 2
},
{
"unit" : "Cup",
"name" : "Palya\/Curry",
"quantity" : 1
}
],
"is_active" : 1,
"image" : "nds.jpg",
"menu_name" : "Normal Diet South"
},
{
"menu_code" : "NCCD",
"items" : [
{
"menu_code" : "NDS",
"name" : "Monday"
},
{
"menu_code" : "NDN",
"name" : "Tuesday"
}
],
"is_active" : 1,
"image" : "NCCD.jpg",
"menu_name" : "Normal Combo Corporate Diet"
}
]
Today 2 format i have .In this both format only my data will come from response.And i need to show them in collection view.
My api call :
func getAllCatogory(){
TransportManager.sharedInstance.AllCatogory { (dt, err) in
if let _ = err{
}else{
if let data = dt as? String {
let pro = Mapper<AllCatagories>().map(JSONString: data)
print(data) // getting data
print(pro as Any) // getting nil
}
}
}
}
My model :
class AllCatagories: Mappable{
var menu_code = ""
var items: Array<AllCatProducts> = []
var is_active = 0
var image = ""
var menu_name = ""
required init?(map: Map) {
}
init() {
}
func mapping(map: Map) {
menu_name <- map["menu_name"]
is_active <- map["is_active"]
menu_code <- map["menu_code"]
image <- map["image"]
items <- map["items"]
}
}
Below i have created one more model class for the item inside my json.
class AllCatProducts: Mappable{
var name = ""
var quantity = 0
var unit = ""
var menu_code = ""
required init?(map: Map) {
}
init() {
}
func mapping(map: Map) {
name <- map["name"]
quantity <- map["quantity"]
unit <- map["unit"]
menu_code <- map["menu_code"]
}
}
The issues is i am getting nil in my pro.Not sure when i am doing wrong.
Thanks
You can try
struct AllCatagories: Codable {
let menuCode: String
let items: [AllCatProducts]
let isActive: Int
let image, menuName: String
}
struct AllCatProducts: Codable {
let unit: String?
let name: String
let quantity: Int?
let menuCode: String?
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
guard let str = dt as? String else { return }
let res = try decoder.decode([AllCatagories].self, from:str.data(using: .utf8)!)
print(res)
}
catch {
print(error)
}

Swift: display arrayobject to tableView

im trying to dispaly array object come from api response as [[String: Any]] at table view
and thats my struct
class CategoriesDep: NSObject {
var depName: String
var depImage: String
var subName = [subData]()
init?(dict: [String: JSON]) {
guard let image = dict["main_department_image"]?.imagePath, !image.isEmpty else { return nil }
self.depImage = image
self.depName = (dict["main_department_name"]?.string)!
}
struct subData {
var dep: String
init(dic: [String: Any]) {
self.dep = dic["sub_department_name"] as! String
}
}
}
Please check below code to parse your json
class CategoriesDep: NSObject {
var depName: String
var depImage: String
var subName = [subData]()
init?(dict: [String: Any]) {
guard let image = dict["main_department_image"] as? String, !image.isEmpty else { return nil }
self.depImage = image
self.depName = (dict["main_department_name"] as? String)!
subName = []
for subDict in (dict["sub_depart"] as? [[String:Any]] ?? []){
subName.append(subData(dic: subDict))
}
}
}
struct subData {
var dep: String
var image :String
var id : String
init(dic: [String: Any]) {
self.dep = dic["sub_department_name"] as! String
self.image = dic["sub_department_image"] as! String
self.id = dic["sub_department_id"] as! String
}
}
and if you want to access subdata struct out side of CategoriesDep class then declare structure outside CategoriesDep class
Parse your given json Respoise like
let json = [
[ "sub_depart" : [
[ "sub_department_name" : "hos", "sub_department_id" : "6", "sub_department_image" : "23.jpg"
]
],
"main_department_id" : "2",
"main_department_name" : "main ",
"main_department_image" : "14.jpg"
],
]
var catDepart : [CategoriesDep] = []
for dict in json {
catDepart.append(CategoriesDep(dict: dict)!)
}
print(catDepart[0].subName[0].dep)
You could use Codabel protocol to be more swifty ;) and cleaning up the code.
let jsonString = "[{\"sub_depart\" : [ {\"sub_department_name\" : \"hos\", \"sub_department_id\" : \"6\", \"sub_department_image\" : \"23.jpg\" } ], \"main_department_id\" : \"2\", \"main_department_name\" : \"main \", \"main_department_image\" : \"14.jpg\"}]"
struct CategoriesDep: Codable {
let mainDepartmentName: String
let mainDepartmentImage: String
let mainDepartmentId: String
var subDepart: [SubData] = []
}
struct SubData: Codable {
let subDepartmentName: String
let subDepartmentImage: String
let subDepartmentId: String
}
if let jsonData = jsonString.data(using: .utf8) {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
var departments: [CategoriesDep]? = try? decoder.decode([CategoriesDep].self, from: jsonData)
...
}
Note the decoder.keyDecodingStrategy = .convertFromSnakeCase here which is mapping the underscore (snake_case) API property names to your camelCase ones.
If you need different property names you have to implement CodingKeys enum to map them.
For more detailed information check this link.

How to create a function to show reviews in a view of my application (Swift-JSON)

I'm following https://developers.google.com/places/web-service/details this doc to add all the information about a place, and for example to add "geometry"
"geometry" : {
"location" : {
"lat" : -33.866651,
"lng" : 151.195827
},
i created this function in my class that work well
private let geometryKey = "geometry"
private let locationKey = "location"
private let latitudeKey = "lat"
private let longitudeKey = "lng"
class EClass: NSObject {
var location: CLLocationCoordinate2D?
init(placeInfo:[String: Any]) {
placeId = placeInfo["place_id"] as! String
// coordinates
if let g = placeInfo[geometryKey] as? [String:Any] {
if let l = g[locationKey] as? [String:Double] {
if let lat = l[latitudeKey], let lng = l[longitudeKey] {
location = CLLocationCoordinate2D.init(latitude: lat, longitude: lng)
}
}
}
}
but but i'm having difficulty adding "reviews"
"reviews" : [
{
"author_name" : "Robert Ardill",
"author_url" : "https://www.google.com/maps/contrib/106422854611155436041/reviews",
"language" : "en",
"profile_photo_url" : "https://lh3.googleusercontent.com/-T47KxWuAoJU/AAAAAAAAAAI/AAAAAAAAAZo/BDmyI12BZAs/s128-c0x00000000-cc-rp-mo-ba1/photo.jpg",
"rating" : 5,
"relative_time_description" : "a month ago",
"text" : "Awesome offices. Great facilities, location and views. Staff are great hosts",
"time" : 1491144016
}
],
i tried to follow the same concept of the function i created for geometry like this
if let t = place.details?["reviews"] as? [String:Any] {
if let n = t["author_name"], let m = t["text"] {
Mylabel.text = "\(t)"
}
but is not working, i also tried to add a breakpoint and only the first line enters. What can i do? How can i create a build to show the review with a label or anything i need?
Take advantage of Codable in Swift 4. You can simply convert your JSON into a specific struct. e.g. Based on your JSON:
let json = """
{
"reviews" : [
{
"author_name" : "Robert Ardill",
"author_url" : "https://www.google.com/maps/contrib/106422854611155436041/reviews",
"language" : "en",
"profile_photo_url" : "https://lh3.googleusercontent.com/-T47KxWuAoJU/AAAAAAAAAAI/AAAAAAAAAZo/BDmyI12BZAs/s128-c0x00000000-cc-rp-mo-ba1/photo.jpg",
"rating" : 5,
"relative_time_description" : "a month ago",
"text" : "Awesome offices. Great facilities, location and views. Staff are great hosts",
"time" : 1491144016
}
]
}
"""
You can convert it into a Response struct using the following code:
struct Response: Codable {
struct Review: Codable, CustomStringConvertible {
let text: String
let authorName: String
var description: String {
return "Review text: \(text) authorName: \(authorName)"
}
enum CodingKeys: String, CodingKey {
case text
case authorName = "author_name"
}
}
let reviews: [Review]
}
do {
if let data = json.data(using: .utf8) {
let decoder = JSONDecoder()
let decoded = try decoder.decode(Response.self, from: data)
print(decoded.reviews)
} else {
print("data is not available")
}
} catch (let e) {
print(e)
}
In your code t is not a Dictionary it is an Array instead. So try doing something like this. Rest of that you can change as per your logic.
if let t = place.details?["reviews"] as? [String:Any] {
for dic in t {
if let n = dic["author_name"], let m = dic["text"] {
Mylabel.text = "\(t)"
}
}
}
Yeah, but You can also try to make it like that:
struct reviews: Codable{
var reviews: [review]?
}
struct review: Codable{
var author_name: String?
var author_url: String?
var language: String?
var profile_photo_url: String?
var rating: Int?
var relative_time_description: String?
var text: String?
var time: Int?
}
And then:
if let dict = place.details?["reviews"] as? [String: Any],
let dataToDecode = dict.data(using: .utf8){
do{
let decodedReviews = try JSONDecoder().decode(reviews.self, from: dataToDecode)
// here you have decoded reviews in array
}catch let err{
print(err)
}
}

How To increase index of Array when the value is Dynamic (Swift)

I am Getting a Dynamic Array which Consist (Dictionary with Array ) and want to increase the Index of Array and will go on to Next Dictionary on action.
After Parsing The Value in swapLibs
var currentQuizIndex = 0
func Dataparsed() {
ServiceManager.service(ServiceType.POST, path: urslStr, param: nil, completion: { (sucess, response, error, code) -> Void in
if (code == 200) {
let QuizData = (swapLibs?.valueForKey("quiz") as! NSArray)
let quizData = playInfo.PlayQuizInfo(QuizData[self.currentQuizIndex] as? NSDictionary)
self.playQuizArray.addObject(quizData)
self.playQuizTitle?.text = quizData.quizQuestion
self.playQImage.sd_setImageWithURL(NSURL(string: quizData.quizQImage!))
self.QNumber?.text = "\(self.Qno)/\(self.noofQuestion)"
}
})
}
And The Modal is
class playInfo: NSObject {
var quizId : String? = ""
var quizQId : String? = ""
var quizQImage : String? = ""
var quizQuestion : String? = ""
var quizType : String? = ""
var quizIndex : String? = ""
class func PlayQuizInfo(dict: NSDictionary?) -> playInfo {
let Pinfo = playInfo()
Pinfo.WrapPlayQuiz(dict)
return Pinfo
}
func WrapPlayQuiz(dict: NSDictionary?) {
if dict == nil {
return
}
self.quizId = dict!.objectForKey("quizId") as? String
self.quizIndex = dict!.objectForKey("index") as? String
self.quizQImage = dict!.objectForKey("QuesImage") as? String
self.quizQuestion = dict!.objectForKey("question") as? String
self.quizType = dict!.objectForKey("Type") as? String
self.quizQId = dict!.objectForKey("questionId") as? String
}
}
Here is Structure
{
"quiz":[
{
"quizId":"7295",
"QuesImage":"http:\/\/proprofs.com\/api\/ckeditor_images\/man-approaches-woman1(1).jpg",
"question":"How do you know him?",
"questionId":"216210",
"Type":"PQ",
"index":4,
"keys":[
{
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
},
{ },
{ },
{ },
{ }
]
},
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ }
]
}
Each Dictionary is Containing same Key As above
Any Help Will Be Appreciated.Thanks.
As I don't have ServiceManager at my end so I have created this code hypothetically. It might solve you issue of saving all data in to one array. It also adds keys in to array as an object.
EDIT 1 : correct QuizKey object array formation. Let me know if any kind of error occurs, as I am unable to test it at my end.
Edit 2: I have made a general ViewController its working perfectly.Try running this View Controller file and you will see the results.
class TestVC: UIViewController {
//An Array similar to the response you are getting from the server
var response:[AnyObject] = [
[
"quizId" : "1111",
"QuesImage" : "http://proprofs.com/api/ckeditor_images/man-approaches-woman1(1).jpg",
"question" : "How do you know him?",
"questionId" : "216210",
"Type" : "PQ",
"index" : 4,
"keys":[
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
]
]
],
[
"quizId" : "2222",
"QuesImage" : "http://proprofs.com/api/ckeditor_images/man-approaches-woman1(1).jpg",
"question" : "How do you know him?",
"questionId" : "216210",
"Type" : "PQ",
"index" : 4,
"keys":[
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
],
[
"answerId":"8266",
"option":"He's in one or more of my classes, and we're good friends.",
"AnsImage":"Image Not Available"
]
]
]
]
var playQuizArray:[playInfo]! = []
override func viewDidLoad() {
super.viewDidLoad()
print(response)
for dict in response {
self.playQuizArray.append(playInfo.PlayQuizInfo(dict as? [String:AnyObject]))
}
print(self.playQuizArray)
let quiz = self.playQuizArray[0]
print("quizId \(quiz.quizId)")
print("keyAnswerId \(quiz.quizKeys![0].keyAnswerId)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class playInfo: NSObject {
var quizId : String? = ""
var quizQId : String? = ""
var quizQImage : String? = ""
var quizQuestion : String? = ""
var quizType : String? = ""
var quizIndex : String? = ""
//quizKeys will contain quiz array
var quizKeys : [QuizKey]? = []
class func PlayQuizInfo(dict: [String:AnyObject]?) -> playInfo {
let Pinfo = playInfo()
Pinfo.WrapPlayQuiz(dict)
return Pinfo
}
func WrapPlayQuiz(dict: [String:AnyObject]?) {
if dict == nil {
return
}
self.quizId = dict!["quizId"] as? String
self.quizIndex = dict!["index"] as? String
self.quizQImage = dict!["QuesImage"] as? String
self.quizQuestion = dict!["question"] as? String
self.quizType = dict!["Type"] as? String
self.quizQId = dict!["questionId"] as? String
//add key object array to the quizKeys
if let arrKeys = dict!["keys"] as? [AnyObject] {
for arr in arrKeys {
let key:QuizKey = QuizKey.QuizKeyInfo(arr as? [String : AnyObject])
self.quizKeys?.append(key)
}
}
}
}
class QuizKey: NSObject {
var keyAnswerId : String? = ""
var keyOption : String? = ""
var keyAnsImage : String? = ""
class func QuizKeyInfo(dict: [String:AnyObject]?) -> QuizKey {
let QKeys = QuizKey()
QKeys.WrapQuizKeys(dict)
return QKeys
}
func WrapQuizKeys(dict: [String:AnyObject]?) {
if dict == nil {
return
}
self.keyAnswerId = dict!["answerId"] as? String
self.keyOption = dict!["option"] as? String
self.keyAnsImage = dict!["AnsImage"] as? String
}
}

Resources