unable to convert coma seperated string to array of ints in swift - arrays

I am getting string of ints, i need to convert that in array if ints
i need like this [8,9,10]
let stringOfints = "8,9,10"
let arrOfIds = stringOfints?.components(separatedBy: ",")
0/p:
["8","9", "10"]
EDIT: here i need to check id with string of ints
my json like this
{
"jsonrpc": "2.0",
"result": {
"sub_category": [
{
"id": 2,
"title": "Logo Design"
},
{
"id": 3,
"title": "banner design"
},
{
"id": 5,
"title": "business web site"
},
{
"id": 10,
"title": "Business Card Design"
}
]
}
}
code: here arrOfIds are [2, 3] but when i compare arrOfIds with json id and if its match then appending its title to arrSubCat but if i print arrSubCat at end of for loop then why all titels are coming...plz help
var arrSubCat:[String] = []
private func getSubCategoryServiceIDs() {
let param = ["category_id" : categoryID!]
APIReqeustManager.sharedInstance.serviceCall(param: param, url: CommonUrl.get_sub_category) { [weak self] (resp) in
self?.getSubCategoryIDs = GetSubCatModel(dictionary: resp.dict as NSDictionary? ?? NSDictionary())
if self?.getServiceDetails?.result?.serviceDetails?.sub_cat_group != nil{
let kat = self?.getSubCategoryIDs?.result?.sub_category ?? []
let value = self?.getServiceDetails?.result?.serviceDetails?.sub_cat_group
let arrOfIds = value?.components(separatedBy: ",").compactMap { Int($0) }
for singleCat in kat{
if ((arrOfIds?.contains(singleCat.id ?? 0)) != nil){
self?.arrSubCat.append(singleCat.title ?? "")
}
}
print("array of sub cat \(self?.arrSubCat)")//getting all titles why?
self?.collectionView.reloadData()
}
}
}
o/p
array of sub cat (["Logo Design", "banner design", "business web site", "Business Card Design"])

Previous Answer
You have to convert the String to Int
let stringOfints = "8,9,10"
let arrOfIds = stringOfints.components(separatedBy: ",").compactMap { Int($0) }
Updated Answer
Modify the code inside API call like below and try.
let arrOfIds = value?.components(separatedBy: ",").compactMap { Int($0) } ?? []
for singleCat in kat {
if arrOfIds.contains(singleCat.id ?? 0) {
self?.arrSubCat.append(singleCat.title ?? "")
}
}

Related

Unable to get JSON response selected city id from dropdown in swift

JSON response like this
{
"result": {
"cities": [
{
"id": 1,
"city": "North and Middle Andaman",
"state_id": 32
},
{
"id": 2,
"city": "South Andaman",
"state_id": 32
},
{
"id": 3,
"city": "Nicobar",
"state_id": 32
},
{
"id": 330,
"city": "Mumbai suburban",
"state_id": 12
},
I am showing cities in textfield with TextFieldEditingChanged and dropdown
code: with this code i can show city list in dropdown and got selected city in textfield but i need selected city id as well.. which i am unable to get
if i print print(item, self?.cityId). here Mumbai suburban id is 330 but got dropdown index 2... how do i get selected city id from dropdown, please guide me
o/p
Mumbai suburban Optional(2)
#IBAction func cityTextFieldEditingChanged(_ sender: UITextField) {
var tempArray = [String]()
if sender.text?.count != 0 {
for eachData in cityResultDict?.cities ?? []{
if let wordToSearch = sender.text{
let range = eachData.city?.lowercased().range(of: wordToSearch, options: .caseInsensitive, range: nil, locale: nil)
if range != nil {
tempArray.append(eachData.city ?? "")
}
}
}
}
showDropDown(with: tempArray, from: sender) { [weak self] (item, index) in
self?.locationTextField.text = item
self?.cityId = cityResultDict?.cities?[index].id ?? 0
print(item, self?.cityId)
}
}
if i print print(item, self?.cityId). here Mumbai suburban id is 330 but got dropdown index 2..
Because you are making a new array which is tempArray matching with your search condition when you showDropDown.
I don't know how you implement your showDropDown. But this is a key for your code
Code will be like this
var tempArray = [String]()
var tempCityId = [String]() // I not recommend slipt like this which one is for name city and one is for your id
if sender.text?.count != 0 {
for eachData in cityResultDict?.cities ?? []{
if let wordToSearch = sender.text{
let range = eachData.city?.lowercased().range(of: wordToSearch, options: .caseInsensitive, range: nil, locale: nil)
if range != nil {
tempArray.append(eachData.city ?? "")
// make new array to store your cityId too
tempId.append(eachData.cityId ?? "")
}
}
}
}
showDropDown(with: tempArray, from: sender) { [weak self] (item, index) in
self?.locationTextField.text = item
self?.cityId = tempCityId[index].id ?? 0 // get the id form your tempCityId too
print(item, self?.cityId)
}
Notice: This way I don't recommend. You can make a new struct which store all your reaching City or a struct only store your cityName and cityId which easier for you.
I build this way just for easier for you to realize and because I don't know how you build your showDropDown

Issue displaying array data inside UIAlert View

Essentially I would like to parse the JSON received from a url and display the data inside of alert popup.
I am able to do this with a simple array below but don't know how this can be done with an JSON array from a URL.
Currently working:
let jsonObj:[String: Any] = ["error": [
"email": ["The email has already been taken."],
"phone": ["The phone has already been taken."]]
]
if let errorMsgs = jsonObj["error"] as? [String: [String]] {
let errMsg = errorMsgs.values.map { $0.reduce("", +) }.joined(separator: "\n")
print(errMsg)
self.presentAlert(withTitle: "Try again", message: errMsg)
}
JSON Array:
var structure = [Struct]()
private func fetchJSON() {
guard let url = URL(string: "url.com")
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "code=\(codeValue)".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
do {
self.structure = try JSONDecoder().decode([Struct].self,from:data)
}
catch {
print(error)
}
}.resume()
}
struct Struct: Decodable {
let id: Int
let reasons: String
}
Sample JSON Array:
[
{
"id": 1,
"reasons": "Test"
},
{
"id": 3,
"reasons": "Test"
}
]
How can I get the reasons string from the array to populate in the alert similar to above.
UPDATE:
To Print the records in the alert I have done the following but it only prints one record in the alert:
for item in self.structure {
print(item.reasons)
let errMsg = [item.reasons].compactMap { $0 }.joined(separator: "\n")
self.presentAlert(withTitle: "Try again", message: errMsg)
}
Here I have created example from your code.
First of all replace your Codable with:
// MARK: - Reason
struct Reason: Codable {
let id: Int
let reasons: String
}
typealias Reasons = [Reason]
Here is your server response in JSON String formate:
let json = """
[
{
"id": 1,
"reasons": "Test"
},
{
"id": 3,
"reasons": "Test"
}
]
"""
Then I have converted it to Data only for testing purpose:
let data = json.data(using: .utf8)!
And you can parse it with
do {
self.reasonsData = try JSONDecoder().decode(Reasons.self, from:data)
for item in self.reasonsData {
print(item.reasons) //This will print reasons.
}
}
catch {
print(error)
}
UPDATE:
If you want all reasons in one string then replace
for item in self.reasonsData {
print(item.reasons)
}
with
let errMsg = self.reasonsData.compactMap { $0.reasons }.joined(separator: "\n")

How to use key and value from json response in tableview in iOS swift?

In tableview, each cell with key and value labels, i can able to pass static key value to tableview but now trying to get data from Json response to show in tableview.
here is my json response:
{
"d": {
"results": [
{
"__metadata": {
"id": "http://192.168.41.27:8009/sap/opu/odata/sap/Z_MM_PO_01_SRV/POItemSetSet('4500022401')",
"uri": "http://192.168.41.27:8009/sap/opu/odata/sap/Z_MM_PO_01_SRV/POItemSetSet('4500022401')",
"type": "Z_MM_PO_01_SRV.POItemSet"
},
"PoDocNo": "4500022401",
"Item": "00010",
"Material": "RMECC_MOB1",
"StorageLocation": "3001",
"MatGroup": "00107",
"Quantity": "2.000",
"OrderUnit": "KG",
"NetPrice": "1000.000",
"UnitofPrice": "1.000",
"ItemCat": "0",
"Requistor": ""
},
{
"__metadata": {
"id": "http://192.168.41.27:8009/sap/opu/odata/sap/Z_MM_PO_01_SRV/POItemSetSet('4500022401')",
"uri": "http://192.168.41.27:8009/sap/opu/odata/sap/Z_MM_PO_01_SRV/POItemSetSet('4500022401')",
"type": "Z_MM_PO_01_SRV.POItemSet"
},
"PoDocNo": "4500022401",
"Item": "00020",
"Material": "RMECC_MOB1",
"StorageLocation": "3001",
"MatGroup": "00107",
"Quantity": "2.000",
"OrderUnit": "KG",
"NetPrice": "1000.000",
"UnitofPrice": "1.000",
"ItemCat": "0",
"Requistor": ""
}
]
}
}
here i'm getting json response:
extension PoItemDetailsViewController {
func GetPoItemCount() {
if orderNo != nil {
// Call API
print("orderni::\(orderNo!)")
PoVendorListApiManager.sharedInstance.getPoListWithModel(orderString: orderNo!){ (json:JSON) in
// return json from API
if let categories = json["d"]["results"].dictionary {
print("catefory::\(self.categories)")
for (key, value) : (String, JSON) in categories {
self.dict[key] = value.object as AnyObject
}
print("dict:::\(self.dict)")
// for key in categories.keys {
// if let category =
categories[key]?.stringValue {
//
self.categories.updateValue(category, forKey: key)
// }
//
// }
}
print("catefory::\(self.categories)")
}
}
}
}//extension
here is my model:
import SwiftyJSON
struct poItems {
var key: String?
var value: String?
}
here is my static value i have passed to table view:
private var PoItems: [poItems]?
private var poVendorItemArray = [PoVendorModel]()
private func loadPoItems() -> [poItems] {
var tempItems = [poItems]()
let item1 = poItems.init(key: "Material#", value: "")
let item2 = poItems.init(key: "Quantity", value: "Bottles")
let item3 = poItems.init(key: "StorageLocation", value: "KP04")
let item4 = poItems.init(key: "PoDocNo", value: "KP Suppliers")
let item5 = poItems.init(key: "NetPrice", value: "1000")
return tempItems
}
how can i pass json reponse with key and value dynamically into tableview?
Any help much appreciates pls...
Please reread my answer in your earlier question (or read the JSON)
The value for results is an array
if let categories = json["d"]["results"].array {
print("category::\(self.categories)")
for category in categories {
for (key, value) in category {
print(key, value)
}
}
}
And – as suggested in many of your previous questions and in the comments – you are encouraged to drop SwiftyJSON and use Codable.

How to return a value of Dictionary that satisfies the given predicate?

I can't solve next problem. I get an array of Dictionaries from JSON with the same keys and different values.
For example:
{
"data": [{
"name": "Anna",
"features": {
"age": "18",
"hobby": "football"
}
}, {
"name": "Peter",
"data": {
"age": "16",
"hobby": "computer games"
}
}, {
"name": "Peter",
"data": {
"age": "25",
"hobby": "chess",
"job": "fireman"
}
}
],
"view": ["Peter", "Anna", "Peter"]
}
This is my structures for Decoding:
struct Object: Decodable {
let objectData: [DictionaryData]
let bjectView: [String]
}
struct DictionaryData: Decodable {
let name: String
let features: Features?
let data: DataClass?
}
struct DataContainer: Decodable {
let age, hobby: String
let job: String?
}
struct Features: Decodable {
let age, hobby: String
}
This is the point where I stuck. I use filter but it returns Bool while I need a value of dictionaries:
var items = [ModelItem]()
var singleObject: Object!
func jsonParsing(completionHandler: #escaping (([ModelItem], Error?) -> Void)) {
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { DispatchQueue.main.async {completionHandler([], error)}
return
}
do {
self.singleObject = try JSONDecoder().decode(Object.self, from: data)
let sequenceArray = self.singleObject.objectView
for i in sequenceArray {
if i == "Peter" {
if let objectName = self.singleObject?.objectData.filter({ return $0.name == "Peter"}) ... {
let firstItem = ModelFirstItem(text: ...) //here should be a value
self.items.append(firstItem)
}
}
else if i == "Anna" {
...
}
}
}
DispatchQueue.main.async {completionHandler(self.items, nil)}
} catch {
print("Error serializing json:", error)
}
} .resume()
}
How can I get age, hobby and job values?
Thank you!
Codable Model of the JSON
struct Welcome: Codable {
let data: [Datum]
let view: [String]
}
struct Datum: Codable {
let name: String
let features: Feature?
let data: Data?
}
struct Data: Codable {
let age, hobby: String
let job: String?
}
struct Feature: Codable {let age, hobby: String}
Decode the JSON
let decoder = JSONDecoder()
let decodedObject = try! decoder.decode(Welcome.self, from: JSON)
let filterdPeter = decodedObject.data.filter {$0.name == "Peter"}.map({$0.data})
filterdPeter.forEach {print($0)}
if let json = object as? [String: Any],
let dataJSON = json["data"] as? [[String: Any]] { //in the data field you have an array of dictionaries, maybe this is what you're stuck on?
dataJSON.forEach { jsonElement in
if let name = jsonElement["name"] as? String, name == "Peter" {
print(jsonElement["data"])
}
}
}

Filter a Parse query with an Array of [AnyObject] in Swift

I have an array of AnyObject objects in Swift (eventually, this array will be populated by querying a Parse database). Each object in the array has attributes of a publication, such as fullTitle, url, and journal. How can I filter the array to select all objects that match the search string for any value (e.g. where the fullTitle, url, or journal include "Forbes")?
Below is example code from a playground. First the sample array:
var publication1 = [
"fullTitle": "My first blog",
"url": "www.forbes.com/post1",
"journal": "Forbes
]
var publication2 = [
"fullTitle": "My second blog",
"url": "www.wsj.com/post1",
"journal": "Wall Street Journal"
]
var publications: [AnyObject] = [publication1, publication2]
Then, the filter function:
func filterContentForSearchText(searchText: String) {
let filteredPublications = publications.filter() {
if let fullTitle = ($0)["fullTitle"] as? String {
return fullTitle.rangeOfString(searchText) != nil
} else {
return false
}
}
}
Now, if I call the function with "first" as an argument, it should return the first object out of the array:
println(filterContentForSearchText("first"))
However, this command gives no result. How can I fix this? Also, how can I query all fields of the object for the searchText, not just the fullTitle field?
Thank you.
Here's a simple example that returns an array of matches in all fields:
func filterContentForSearchTextInAllFields(searchText: String) -> [String] {
var results = [String]()
for publication in publications {
for (key, value) in publication {
if (value as NSString).containsString(searchText) {
results.append(value)
}
}
}
return results
}
println(filterContentForSearchTextInAllFields("blog"))
This one only works on titles:
func filterContentForSearchText(searchText: String) -> [String] {
var results = [String]()
for publication in publications {
if let fullTitle = publication["fullTitle"] {
if (fullTitle as NSString).containsString(searchText) {
results.append(fullTitle)
}
}
}
return results
}
println(filterContentForSearchText("first"))
UPDATE
Here's a version for what you've asked in the comments:
func filterContentForSearchText(searchText: String) -> [[String:String]] {
var results = [[String:String]]()
for publication in publications {
if let fullTitle = publication["fullTitle"] as? String {
if (fullTitle as NSString).containsString(searchText) {
results.append(publication as! [String : String])
}
}
}
return results
}
println(filterContentForSearchText("first"))
Your "rows" are dictionaries: in the loop we assign each one to the "publication" variable, so we just take the one whose title matches the search terms then append it to an array of dictionaries.
Here is the route I went. Instead of an array of AnyObject I just let Swift infer the type
var publications = [publication1, publication2]
func searchPublications(seachText: String) -> [[String: String]] {
let filteredPublications = publications.filter { $0
for (_, value) in $0 {
if let found = value.rangeOfString(seachText, options: NSStringCompareOptions.CaseInsensitiveSearch, range: Range<String.Index>(start: value.startIndex, end: value.endIndex), locale: NSLocale.currentLocale()) {
return true
}
}
return false
}
return filteredPublications
}
Swift 3.0
This is worked for me.
I want filter data by it's status 0 or 1.
var arrRooms:[[String:AnyObject]] = [
[
"id": 30 as AnyObject,
"name": "Earth" as AnyObject,
"status": 0 as AnyObject,
"duration": 10 as AnyObject
],
[
"id": 27 as AnyObject,
"name": "Mars" as AnyObject,
"status": 1 as AnyObject,
"duration": 0 as AnyObject
]
]
let StatusPredicate = NSPredicate(format: "status = 1 ")
let arrFilter:[[String:AnyObject]] = (arrRooms as NSArray).filtered(using: StatusPredicate) as! [[String : AnyObject]]
print(arrFilter);
// output [["name": Mars, "status": 1, "id": 27, "duration": 0]]
it may be useful.thanks

Resources