In Swift, I defined my var as:
var data : [[[String : Any]]] = [[[:]]]
then init it:
for section in 0...1 {
for row in 0...19 {
let streamer = [
"name" : "abcdef"
]
data[section][row] = streamer
}
}
but I'm gettingfatal error: Index out of range. for index data[0][1], but there's not an error for index data[0][0].
Do anybody know why I'm getting this error?
I see the problem, for some reason I was thinking swift would auto insert a section and row when I access them by subscript, but it seems that's not the case, so I changed my init to:
for sectionIndex in 0...1 {
var section : [[String : Any]] = [[:]]
for rowIndex in 0...19 {
let streamer = [
"name" : "abcdef"
]
section.insert(streamer, at: rowIndex)
}
data.insert(section, at: sectionIndex)
}
Related
I want to send array object to web service, but when I try to add array to parameters it gives error. I tried many things but nothing found usefully.
I want to add ("assignees" : newList) in parameter and than send it to web service
Here is my code
var newList = [Assignee]()
var assignee = Assignee()
for u in task.NewWorkList! {
assignee = Assignee()
assignee.assignedEmail = u.Email
assignee.assignedName = u.Name
assignee.assignedSurname = u.Surname
assignee.assignedType = "PERSONEL"
assignee.assignedTo = String(u.Id!)
newList.append(assignee)
}
// in this part newList is an array of assignees.
var assigneeListString = ""
let jsonEncoder = JSONEncoder()
do {
let jsonData = try jsonEncoder.encode(newList)
assigneeListString = String(data: jsonData, encoding: .utf8)!
print("assigneeListString:",assigneeListString)
} catch {
print("error:::")
}
var parameters = [
"taskType" :
[
"code" : "OTHER"
],
"complateButtons": "COMPLATE",
"assignees" : [JSON(assigneeListString)], // does not work
// "assignees" : [JSON(newList)], // does not work
// "assignees" : JSON(newList), // does not work
// "assignees" : newList, // does not work
// "assignees" : assigneeListString, // does not work
"repeatTimeType":"NEVER"
] as [String : Any]
print("parameters:",parameters)
DAL.Service.MakeRequest(url: Constants.Service.Url.newTask,
parameters : parameters,
httpMethod : ServiceMethods.post.rawValue,
resultFunc: serviceResultFunc)
when I print parameters assignee section adds extra semi colon,
[[{"assignedTo":"63659","assignedSurname":"DAVID","assignedType":"PERSONEL","assignedName":"JOE","assignedEmail":"joe#abc.com"},{"assignedTo":"21026","assignedSurname":"GEORGE","assignedType":"PERSONEL","assignedName":"MICHAEL","assignedEmail":"michael#abc.com"}]],
when I manually add assignees to patameters , its ok.
[["assignedTo":"63659","assignedSurname":"DAVID","assignedType":"PERSONEL","assignedName":"JOE","assignedEmail":"joe#abc.com"},{"assignedTo":"21026","assignedSurname":"GEORGE","assignedType":"PERSONEL","assignedName":"MICHAEL","assignedEmail":"michael#abc.com"]],
I solved the problem with below code:
var assigneesList = [[String:Any]]()
for a in task.YeniGorevAtamaList! {
assigneesList.append(
["assignedTo":(a.Id) ?? "0",
"assignedSurname":a.Surname ?? "",
"assignedType":a.assignedType ?? "PERSONEL",
"assignedName":a.Name ?? "",
"assignedEmail":a.Email as Any
]
);
}
let parameters = [
"taskType" :
[
"code" : "DIGER"
],
"assignees" : assigneesList ,
"taskUrls" :
[
]
] as [String : Any]
i have some question and solution, i have class model and it has array inside, my model like this
class WillModel{
var name: String = ""
var documents:[WillItems] = []
var isLFStatus : Bool = false
var isLFShared : Bool = false
}
class WillItems{
var documentPath: String = ""
var documentRemark: String = ""
}
i want to convert the result to JSON Array like
{
"name" : "value",
"documents" : [
{
"documentPath" : "value"
"documentRemark" : "value"
},
{
"documentPath" : "value2"
"documentRemark" : "value2"
}
],
"isLFStatus" : true,
"isLFShared" : true
}
i'm using Swift 3, thanks for your solutions
You can write a simple method to manually encode your model to json as below,
func encodeWillModel(_ model: WillModel) -> [String: Any] {
var params: [String: Any] = [:]
params["name"] = model.name
params["documents"] = model.documents.map({["documentPath": $0.documentPath,
"documentRemark": $0.documentRemark]})
params["isLFStatus"] = model.isLFStatus
params["isLFShared"] = model.isLFShared
return params
}
and you can pass any model to get the json something like,
let willModelJSON = encodeWillModel(yourModel)
But a better approach would be to use any json parsing library(SwiftyJSON, ObjectMapper) that supports Swift 3 or upgrade to Swift 4 and use Encodable/Decodable
So, I'm download data from an API using SwiftyJSON. I'm converting it, and looping through to get all of the results. I'm trying to get a specific part of each result to print out, but I can't seem to get it working.
The code I'm using below takes the json, and loops through it and prints out what is also below. From what is printed, I just want to get the "subject".
do {
let jsonObj = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
let json = JSON(jsonObj)
let pms: NSArray = json["result"]["pms"].arrayValue as NSArray
let arrayLength = pms.count
for var i in (0..<arrayLength) {
let pm = pms[i]
i+=1
}
} catch let error as NSError {
print(error)
}
Which then gives values like:
{
"subject" : "Example",
"status" : 1,
"recipient" : 012345,
"recipientusername" : "Example",
"dateline" : "2018-01-01",
"sender" : 012345,
"pmid" : 012345,
"senderusername" : "DoctorSheep"
}
{
"subject" : "Example 2",
"status" : 1,
"recipient" : 678910,
"recipientusername" : "Example 2",
"dateline" : "2018-01-01",
"sender" : 678910,
"pmid" : 678910,
"senderusername" : "Example 2"
}
If I try something like
let subject = pm["subject"]
I get an error that "Type 'Any' has no subscript members".
let pms = json["result"]["pms"].arrayValue as Array
let arrayLength = pms.count
for var i in (0..<arrayLength) {
let pm = pms[i]
let subject = pm["subject"]
print(subject)
i+=1
}
I have a dictionary, which looks like this:
var dict = [["number" : "1" ], ["number" : "2" ], ["number" : "3" ]]
Now I would like to add new value "level" : "(number of level)" to each index in my dictionary, and it should looks like that:
var dict = [["number" : "1", "level" : "one"], ["number" : "2", "level" : "two" ], ["number" : "3", "level" : "three" ]]
How can I add some value inside existing dictionary in this case?
What you have listed as a dictionary is actually an array of dictionaries. You can add an element to each of the directories by simply iterating the array.
You can use an NSNumberFormatter to convert the digits you have into equivalent words:
var anArray=[["number":"1"],["number":"2"],["number":"3"]]
let numberFormatter=NSNumberFormatter()
numberFormatter.numberStyle=NSNumberFormatterStyle.SpellOutStyle
for i in 0..<anArray.count {
if let numberString=anArray[i]["number"] {
if let number=Int(numberString) {
anArray[i]["level"]=numberFormatter.stringFromNumber(number)
}
}
}
As Paulw11 pointed out, you could use NSNumberFormatter to convert the digits to words:
let dictArray = [["number" : "1" ], ["number" : "2" ], ["number" : "3" ]]
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.SpellOutStyle
let mappedDictArray = dictArray.map { var d = $0; d["level"] = numberFormatter.stringFromNumber(number); return d; }
However, if you're interested in using the level key only for UI purposes, you'd be better writing a Dictionary extension, as there's no point is storing a redundant value:
extension Dictionary {
func levelString() -> String {
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = NSNumberFormatterStyle.SpellOutStyle
return numberFormatter.stringFromNumber(self["number"] as? Int ?? 0)
}
}
which can be used like this:
dictArray[0].level()
I am having the following problem in Swift. First, I declare a data structure, like this:
var books = [String : Dictionary<String, Dictionary<String, Dictionary<String, Array<Dictionary<String, String>>>>>]()
I later initialize the var like this:
books = [
"Fiction" : [
"Genre Fiction" : [
"Mystery" : [
"Classics" : [
["Title" : "Ten Little Indians",
"Author" : "Agatha Christie",
"read" : "no"],
["Title" : "A Study in Scarlet",
"Author" : "Arthur Conan Doyle",
"read" : "no"],
]
]
]
]
]
Note that the compiler does not complain about it. Later, I create a new dictionary which I would like to append to that innermost array, like this:
var bookDict = Dictionary<String, String>()
bookDict = ["title" : dict.valueForKey("title") as! String,
"author": dict.valueForKey("author") as! String,
"read" : dict.valueForKey("read") as! String ]
books["category"]["genre"]["focus"]["set"].append(bookDict)
However, I get a compiler error that "Cannot invoke append with an argument list of type (Dictionary < String, String>)". This is confusing to me because the books data structure is declared such that that innermost array is an array of Dictionary< String, String>.
What am I missing?
It's not clear during compile time if the key is really present in the dictionary so dictionaries always return optional values. You have to check this optionals:
if let category = books["Fiction"] {
if let genre = category["Genre Fiction"] {
if let focus = genre["Mystery"] {
if var set = focus["Classics"] {
set.append(bookDict)
}
}
}
}
Or you can do it also like this:
books["Fiction"]?["Genre Fiction"]?["Mystery"]?["Classics"]?.append(bookDict)