how to get the indexpath of selected Action sheet picker Swift - json

I have got myself into confusion.I need someone to help me.
I have been trying to use Action sheet picker and everything was good but I need to get the selected item. How can I do it?
ActionSheetMultipleStringPicker.show(withTitle: "Select Country", rows: [
countriesArray,], initialSelection: [0],
doneBlock: {
picker, indexes, values in
print("values = \(values)")
print("indexes = \(indexes)")
print("picker = \(picker)")
DispatchQueue.main.async {
// Update UI
self.performSegue(withIdentifier: "pdfsegue", sender: nil)
}
return
}, cancel:
{
ActionMultipleStringCancelBlock in return
}, origin: sender)
these are my arrays:
var emiratesArray = [String]()
var emiratesIdArray = [Int]()
I am getting values into my arrays from JSON:
let url = NSURL(string: EMIRATES_URL)
URLSession.shared.dataTask(with: (url as?URL)!, completionHandler: {(data,response,error) ->
Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
print(jsonObj.value(forKey: "data")!)
if let messageArray = jsonObj.value(forKey: "data") as? NSArray
{
for message in messageArray
{
if let messageDict = message as? NSDictionary
{
if let data = data {
let successmessage = jsonObj.value(forKey: "success") as? Int
if(successmessage == 1)
{
if let emirate_name = messageDict.value(forKey: "emirate_name")
{
self.emiratesArray.append(emirate_name as! String)
print(emirate_name)
}
if let company_id = messageDict.value(forKey: "id")
{
self.emiratesIdArray.append(company_id as! Int)
print(company_id)
}
} else
{
}
}
}
}
}
}
}).resume()
someone help me How to get the selected item?If i were using tableview then I would have taken the id from the [indexpath.row] but in UIActionsheet picker,I dont know how get the id of selected value. Please someone help me please

I didn't found any Custom Class in your given code. You can create a class like below:
class Emirate: NSObject {
var id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
override var description: String {
return self.name
}
}
I have override the description property because ActionSheetMultipleStringPicker shows description of object given in the array if it is not String.
Declare your Emirate array
var emiratesArray = [Emirate]()
Your API request and Parsing should be like this:
let url = NSURL(string: "EMIRATES_URL")
URLSession.shared.dataTask(with: (url as?URL)!, completionHandler: {(data,response,error) ->
Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
{
print(jsonObj.value(forKey: "data")!)
if let messageArray = jsonObj.value(forKey: "data") as? NSArray
{
for message in messageArray
{
if let messageDict = message as? NSDictionary
{
if let data = data {
let successmessage = jsonObj.value(forKey: "success") as? Int
if(successmessage == 1)
{
if let emirate_name = messageDict.value(forKey: "emirate_name") as? String, let company_id = messageDict.value(forKey: "id") as? Int
{
self.emiratesArray.append(Emirate(id: company_id, name: emirate_name))
print(emirate_name)
}
} else
{
}
}
}
}
}
}
}).resume()
Now feed your action sheet self.emiratesArray
ActionSheetMultipleStringPicker.show(withTitle: "Select Country", rows: [
self.emiratesArray], initialSelection: [0],
doneBlock: {
picker, indexes, values in
print("values = \(values)")
print("indexes = \(indexes)")
print("picker = \(picker)")
DispatchQueue.main.async {
// Update UI
self.performSegue(withIdentifier: "pdfsegue", sender: nil)
}
return
}, cancel:
{
ActionMultipleStringCancelBlock in return
}, origin: sender)
You will now get the selected Emirate class objects in values array.
N.B- This code is just to give you an idea about how it can work.

Related

How to get json fields?

I follow a lesson from one course
And I need to get json, but i want get another json than in a lesson.
So this is my json:
https://api.scryfall.com/cards/search?q=half
And code:
struct Card {
var cardId: String
var name: String
var imageUrl: String
var text: String
init?(dict: [String: AnyObject]){
guard let name = dict["name"] as? String,
let cardId = dict["cardId"] as? String,
let imageUrl = dict["imageUrl"] as? String,
let text = dict["text"] as? String else { return nil }
self.cardId = cardId
self.name = name
self.imageUrl = imageUrl
self.text = text
}
}
class CardNetworkService{
private init() {}
static func getCards(url: String, completion: #escaping(GetCardResponse) -> ()) {
guard let url = URL(string: url) else { return }
NetworkService.shared.getData(url: url) { (json) in
do {
print ("ok1")
let response = try GetCardResponse(json: json)
print ("ok2")
completion(response)
} catch {
print(error)
}
}
}
}
class NetworkService {
private init() {}
static let shared = NetworkService()
func getData(url: URL, completion: #escaping (Any) -> ()) {
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.async {
completion(json)
}
print(json)
} catch {
print(error)
}
}.resume()
}
}
struct GetCardResponse{
let cards: [Card]
init(json: Any) throws {
guard let array = json as? [[String: AnyObject]] else { throw NetworkError.failInternetError }
var cards = [Card]()
for dictionary in array {
guard let card = Card(dict: dictionary) else { continue }
cards.append(card)
}
self.cards = cards
}
}
Problem in struct GetCardResponse and [[String: AnyObject]] because I dont know how to parse this type of json. I tried to change them in the likeness of json. But I dont really understand how it works and in which part of code i need to put json["data"] or something like this... Help pls. I just want get json fields tcgplayer_id, name, art_crop
As of your code, you can parse the required details as:
struct Card {
var cardId: String = ""
var name: String = ""
var imageUrl: String = ""
var text: String = ""
init(dict: [String: Any]) {
if let obj = dict["name"] {
self.name = "\(obj)"
}
if let obj = dict["tcgplayer_id"] {
self.cardId = "\(obj)"
}
if let obj = dict["image_uris"] as? [String:Any], let url = obj["art_crop"] {
self.imageUrl = "\(url)"
}
if let obj = dict["oracle_text"] {
self.text = "\(obj)"
}
}
static func models(array: [[String:Any]]) -> [Card] {
return array.map { Card(dict: $0) }
}
}
class CardNetworkService{
private init() {}
static func getCards(url: String, completion: #escaping([Card]?) -> ()) {
guard let url = URL(string: url) else { return }
NetworkService.shared.getData(url: url) { (json) in
print ("ok1")
if let jData = json as? [String:Any], let data = jData["data"] as? [[String:Any]] {
let response = Card.models(array: data)
completion(response)
}
completion(nil)
}
}
}
class NetworkService {
private init() {}
static let shared = NetworkService()
func getData(url: URL, completion: #escaping (Any) -> ()) {
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
DispatchQueue.main.async {
completion(json)
}
} catch {
print(error)
}
}.resume()
}
}
CardNetworkService.getCards(url: "https://api.scryfall.com/cards/search?q=half") { (res) in
print(res ?? [])
}
Just paste this code in playground and it'll work.
Happy Coding :)
You are wrong get entry of data field.
First you need get data field in json. And parse to deeper.
Try use the code.
struct GetCardResponse{
let cards: [Card]
init(json: Any) throws {
guard let jsonObject = json as? [String: Any], let data = jsonObject["data"] as? [[String:AnyObject]] else { throw NetworkError.failInternetError }
var cards = [Card]()
for dictionary in data {
guard let card = Card(dict: dictionary) else { continue }
cards.append(card)
}
self.cards = cards
}
}
UPDATE:
init function in Card has something wrong. In your json cardId is not found
Card class maybe like this because cardId, imageUrl, text maybe not found. It is optional
struct Card {
var cardId: String?
var name: String
var imageUrl: String?
var text: String?
init?(dict: [String: AnyObject]){
guard let name = dict["name"] as? String else { return nil }
self.cardId = dict["cardId"] as? String
self.name = name
self.imageUrl = dict["imageUrl"] as? String
self.text = dict["text"] as? String
}
}
Try using Codable to parse the JSON data like so,
Create the models like,
struct Root: Decodable {
let cards: [Card]
enum CodingKeys: String, CodingKey {
case cards = "data"
}
}
struct Card: Decodable {
let tcgplayerId: Int
let name: String
let artCrop: String
}
Now parse your JSON data using,
if let data = data {
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let response = try JSONDecoder().decode(Root.self, from: data)
print(response)
} catch {
print(error)
}
}
You can access the properties in cards of response like so,
response.cards.first?.tcgplayerId

Json parse array in dictionary

I use json api in my application. It can check a company does use electronic Invoice. I have a json data like that:
{
"ErrorStatus": null,
"Result": {
"CustomerList": [
{
"RegisterNumber": "6320036072",
"Title": "VATAN BİLGİSAYAR SANAYİ VE TİCARET ANONİM ŞİRKETİ",
"Alias": "urn:mail:defaultpk#vatanbilgisayar.com",
"Type": "Özel",
"FirstCreationTime": "2014-01-01T05:35:20",
"AliasCreationTime": "2014-01-01T05:35:20"
}
],
"ISEInvoiceCustomer": true
} }
and i use that fucntion for get json data:
func getClientQuery(authorization:String) {
let url = NSURL(string: URLCustomerCheck+strRegisterNumber)
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "GET"
request.addValue(authorization, forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in
if error != nil {
let alert = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
} else {
if data != nil {
do {
let jSONResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! Dictionary<String,AnyObject>
DispatchQueue.main.async {
print(jSONResult)
let result = jSONResult["Result"] as! [String:AnyObject]
//let customerList = result["CustomerList"] as! [[String:AnyObject]]
let ISEInvoiceCustomer = String(describing: result["ISEInvoiceCustomer"])
self._lblISEinvoiceCustomer.text = " \(ISEInvoiceCustomer) "
}
} catch {
}
}
}
}
task.resume()
}
My question is how can i parse "RegisterNumber", "Title".. in "CustomerList"? It's a array that have a member. However i can not parse it in my function.
The customerList line you commented out is needed. Then iterate that array and pull out whatever values you want from each dictionary.
And you really should avoid us as! or any other forced unwrapping when working with JSON. You don't want your app to crash when you obtain unexpected data.
And never use String(describing:) to create a value you will display to a user. The result is inappropriate for display. It's only to be used for debugging purposes.
if let jSONResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any]
DispatchQueue.main.async {
print(jSONResult)
if let result = jSONResult["Result"] as? [String:AnyObject],
let customerList = result["CustomerList"] as? [[String:Any]] {
for customer in customList {
let registrationNumber = customer["RegisterNumber"]
// and any others you need
}
let ISEInvoiceCustomer = result["ISEInvoiceCustomer"] as? Bool ?? false
self._lblISEinvoiceCustomer.text = ISEInvoiceCustomer) ? "Yes" : "No"
}
}
}
Better to Map json to Model , this become easy using Codable
import Foundation
struct Client: Codable {
let errorStatus: ErrorStatus?
let result: Result
enum CodingKeys: String, CodingKey {
case errorStatus = "ErrorStatus"
case result = "Result"
}
}
struct ErrorStatus: Codable {
}
struct Result: Codable {
let customerList: [CustomerList]
let iseInvoiceCustomer: Bool
enum CodingKeys: String, CodingKey {
case customerList = "CustomerList"
case iseInvoiceCustomer = "ISEInvoiceCustomer"
}
}
struct CustomerList: Codable {
let registerNumber, title, alias, type: String
let firstCreationTime, aliasCreationTime: String
enum CodingKeys: String, CodingKey {
case registerNumber = "RegisterNumber"
case title = "Title"
case alias = "Alias"
case type = "Type"
case firstCreationTime = "FirstCreationTime"
case aliasCreationTime = "AliasCreationTime"
}
}
// MARK: Convenience initializers
extension Client {
init(data: Data) throws {
self = try JSONDecoder().decode(Client.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
}
Get customerList :
func getClientQuery(authorization:String) {
let url = NSURL(string: URLCustomerCheck+strRegisterNumber)
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "GET"
request.addValue(authorization, forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in
if error != nil {
let alert = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: UIAlertControllerStyle.alert)
let okButton = UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil)
alert.addAction(okButton)
self.present(alert, animated: true, completion: nil)
} else {
if data != nil {
if let client = try? Client.init(data: data){
client.result.customerList.forEach { (customer) in
print(customer.registerNumber)
}
}
}
}
}
task.resume()
}
let data = resultData
do {
guard let JSONResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : AnyObject],
let resultObject = JSONResult["Result"] as? [String : AnyObject],
let customerList = resultObject["CustomerList"] as? [Anyobject]
else { return }
// Loop the array of objects
for object in customerList {
let registerNumber = object["RegisterNumber"] as? String
let title = object["Title"] as? String
let alias = object["Alias"] as? String
let type = object["Type"] as? String
let firstCreationTime = object["FirstCreationTime"] as? String // Or as a DateObject
let aliasCreationTime = object["AliasCreationTime"] as? String // Or as a DateObject
}
let isEInvoiceCustomer = resultObject["ISEInvoiceCustomer"] as? Bool
} catch {
print(error)
}

How to convert JSON to a dictionary in swift? [duplicate]

Hi I am making an app which works with an API. I have a working code which receives data from the API. But I thought it would be better to make my code a bit cleaner. I want to set the data from the api in an dictionary but I can't get it working. Any help would be appreciated, thanx!
Here is the api result:
I want to set the AutorId and BranchId etc etc in a dictionary.
And this is de code which I have now.
This is the Project class:
class Project: NSObject {
var AuthorId: String?
var BranchId: String?
var CompanyId: String?
var ContactId: String?
var Date: String?
var Deadline: String?
var Description: String?
var Id: String?
var State: String?
init(dictionary: [String: Any]) {
self.AuthorId = dictionary["AuthorId"] as? String
self.BranchId = dictionary["BranchId"] as? String
self.CompanyId = dictionary["CompanyId"] as? String
self.ContactId = dictionary["ContactId"] as? String
self.Date = dictionary["Date"] as? String
self.Deadline = dictionary["Deadline"] as? String
self.Description = dictionary["Description"] as? String
self.Id = dictionary["Id"] as? String
self.State = dictionary["State"] as? String
}
}
and here I am trying to set it in an dictionary:
func apiRequest() {
apiRequestHeader()
var running = false
let urlProjects = NSURL(string: "https://start.jamespro.nl/v4/api/json/projects/?limit=10")
let task = session?.dataTask(with: urlProjects! as URL) {
( data, response, error) in
if let taskHeader = response as? HTTPURLResponse {
print(taskHeader.statusCode)
}
if error != nil {
print("There is an error!!!")
print(error)
} else {
if let content = data {
do {
let dictionary = try JSONSerialization.jsonObject(with: content) as! [String:Any]
print(dictionary)
if let items = dictionary["items"] as? [[String:Any]] {
let project = Project(dictionary: items)
print(project)
self.projects.append(project)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}
catch {
print("Error: Could not get any data")
}
}
}
running = false
}
running = true
task?.resume()
while running {
print("waiting...")
sleep(1)
}
}

How to get a JSON object where a row is equal to variable in Swift

Hy everyone. I am working on an app which works with API's. I am trying to get the "Name" where the "Id" is equal to 1000. When I print the Name it gives me a String value "Todd".
can anyone help me ? This is my JSON response.
And this is my code.
func apiRequestCompani(){
for index in companyId {
let config = URLSessionConfiguration.default
let username = "F44C3FC2-91AF-5FB2-8B3F-70397C0D447D"
let password = "G23#rE9t1#"
let loginString = String(format: "%#:%#", username, password)
let userPasswordData = loginString.data(using: String.Encoding.utf8)
let base64EncodedCredential = userPasswordData?.base64EncodedString()
let authString = "Basic " + (base64EncodedCredential)!
print(authString)
config.httpAdditionalHeaders = ["Authorization" : authString]
let session = URLSession(configuration: config)
let urlProjects = NSURL(string: "https://start.jamespro.nl/v4/api/json/company/"+index+"/?limit=10")
let task = session.dataTask(with: urlProjects! as URL) {
( data, response, error) in
if let taskHeader = response as? HTTPURLResponse {
print(taskHeader.statusCode)
}
if error != nil {
print("There is an error!!!")
print(error)
} else {
if let content = data {
do {
let dictionary = try JSONSerialization.jsonObject(with: content) as! [String:Any]
print(dictionary)
if let items = dictionary["items"] as? AnyObject {
if let klantId = items["Id"] as? String {
if klantId == "1000" {
//print(klantId)
}
}
if let name = items["Name"] as? String {
self.companyName.append(name)
//print(self.companyName)
}
}
}
catch {
print("Error: Could not get any data")
}
}
}
}
task.resume()
//print( urlProjects)
}
}
I think you can do something like this,
var dict: [AnyHashable: Any]? = (response.responseDict()["items"] as? [AnyHashable: Any])
if (dict?.value(forKey: "BranchId") == "1000") {
var name: String? = (dict?.value(forKey: "Name") as? String)
}
Please try the above code snippet.
Hope this will help you.
You can try with below code
let companyIds = ["1000", "1001"]
var companyName = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.apiRequestCompani { (names) in
self.companyName = names // companyName contains all names where id == 1000
print("companyName === \(self.companyName)")
}
}
func apiRequestCompani(completion: #escaping ([String]) -> ()) {
var names = [String]()
var resCount = 0
for companyId in companyIds {
let config = URLSessionConfiguration.default
let username = "F44C3FC2-91AF-5FB2-8B3F-70397C0D447D"
let password = "G23#rE9t1#"
let loginString = String(format: "%#:%#", username, password)
let userPasswordData = loginString.data(using: String.Encoding.utf8)
let base64EncodedCredential = userPasswordData?.base64EncodedString()
let authString = "Basic " + (base64EncodedCredential)!
config.httpAdditionalHeaders = ["Authorization" : authString]
let session = URLSession(configuration: config)
let urlProjects = NSURL(string: "https://start.jamespro.nl/v4/api/json/company/"+companyId+"/?limit=10")
let task = session.dataTask(with: urlProjects! as URL) {
( data, response, error) in
if let taskHeader = response as? HTTPURLResponse {
print(taskHeader.statusCode)
}
if error != nil {
print("There is an error!!!")
print(error ?? "")
} else {
if let content = data {
do {
let dictionary = try JSONSerialization.jsonObject(with: content) as! [String:Any]
if let items = dictionary["items"] as? AnyObject {
if let klantId = items["Id"] as? String, klantId == "1000" {
if let name = items["Name"] as? String {
print("NAME === \(name)")
names.append(name)
}
}
}
}
catch {
print("Error: Could not get any data")
}
}
}
resCount = resCount + 1
if self.companyIds.count == resCount {
completion(names)
}
}
task.resume()
//print( urlProjects)
}
}

Swift : football-data API doesn't work

I'm trying to use football-data.org api. I wrote some code same with before I did sample. But this api is using token and I didn't figured out how to add and do that.
I did these code and nothing happens :
func getData(){
let url = NSMutableURLRequest(URL: NSURL(string: "http://api.football-data.org/v1/soccerseasons/424/fixtures"))
url.addValue("my token is here", forHTTPHeaderField: "X-Auth-Token")
url.HTTPMethod = "GET"
let task = NSURLSession.sharedSession().dataTaskWithRequest(url) { (data, response, error) in
self.setLabels(data!)
}
task.resume()
}
func setLabels(MatchData: NSData){
//var jsonError: NSError?
do{
let json = try NSJSONSerialization.JSONObjectWithData(MatchData, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
if let sys = json["soccerseason"] as? NSDictionary{
if (sys["href"] as? String) != nil{
let seasonsUrl = sys["href"] as! String
print(seasonsUrl)
}
}
}
catch{
//error
}
}
I'm not getting value or something. I'm new with json. What's wrong in my code?
"soccerseason" is in "_links", like this:
if let links = json["_links"] as? [String:AnyObject],
sys = links["soccerseason"] as? [String:String],
seasonsUrl = sys["href"] {
print(seasonsUrl)
}
This is for the main one.
I've also noticed there's one (the same one, actually) in each dictionary in the main array:
if let fixtures = json["fixtures"] as? [[String:AnyObject]] {
for fixture in fixtures {
if let links = fixture["_links"] as? [String:AnyObject],
sys = links["soccerseason"] as? [String:String],
seasonsUrl = sys["href"] {
print(seasonsUrl)
}
}
}
The URLs are in the _links part in each dictionary in the fixtures array:
if let fixtures = json["fixtures"] as? [[String:AnyObject]] {
for fixture in fixtures {
if let links = fixture["_links"] as? [String:[String:String]],
season = links["soccerseason"],
seasonsUrl = season["href"],
awayTeam = links["awayTeam"],
awayTeamUrl = awayTeam["href"] {
print(seasonsUrl)
print(awayTeamUrl)
}
}
}
And awayTeamName and homeTeamName are at the same level than _links inside the array of dictionaries:
if let fixtures = json["fixtures"] as? [[String:AnyObject]] {
for fixture in fixtures {
if let awayTeamName = fixture["awayTeamName"] as? String,
homeTeamName = fixture["homeTeamName"] as? String {
print(awayTeamName)
print(homeTeamName)
}
}
}