Swift reading a json file - json

I am having this error. Cannot invoke 'jsonObject' with an argument list of type '(with: String, options: [Any])'
I am thinking it has to be a different type for the file but not sure.
I don't think doing bundle.main.url would be the correct way to do this. I had seen that in another question that suggested using url, but also not sure how it'd work. Any help would be appreciated, thanks.
This is code for writing into file in InfoViewController
let fileName: String?
let file: FileHandle? = FileHandle(forWritingAtPath: "fileName.json")
if file != nil {
// Set the data we want to write
do{
if let jsonData = try JSONSerialization.data(withJSONObject: fileName!, options: .init(rawValue: 0))
{
// Check if everything went well
//print(NSString(data: jsonData, encoding: 1)!)
let bookCover = (jsonData as AnyObject).value(forKeyPath: "bookCoverImage.image") as? [UIImage]
let bookTitle = (jsonData as AnyObject).value(forKeyPath: "bookTitleLabel.text") as? [String]
let author = (jsonData as AnyObject).value(forKeyPath: "authorLabel.text") as? [String]
let year = (jsonData as AnyObject).value(forKeyPath: "bookYear.text") as? [String]
let pages = (jsonData as AnyObject).value(forKeyPath: "numberOfPages") as? [String]
let ratingStars = (jsonData as AnyObject).value(forKeyPath: "ratingStars.image") as? [UIImage]
let reviews = (jsonData as AnyObject).value(forKeyPath: "totalReviews.text") as? [String]
let description = (jsonData as AnyObject).value(forKeyPath: "descriptionLabel.text") as? [String]
file?.write(jsonData)
// Do something cool with the new JSON data
}
}
catch {
}
// Write it to the file
// Close the file
file?.closeFile()
}
This is the code where the error is occurring. In favoritesListController.
var path: String?
var favoritesList: String?
var bookCoversDisplay = [UIImage]()
var titlesDisplay = [String]()
var authorsDisplay = [String]()
var yearDisplay = [String]()
var pagesDisplay = [String]()
var starRatingDisplay = [UIImage]()
var reviewsDisplay = [String]()
var descriptionsDisplay = [String]()
var bookCovers: UIImage!
var titles: String = ""
var authors: String = ""
var year: String = ""
var pages: String = ""
var starRating: UIImage!
var reviews: String = ""
var descriptions: String = ""
override func viewDidLoad() {
super.viewDidLoad()
path = Bundle.main.path(forResource: "favoritesList", ofType: "json")
do {
favoritesList = try String(contentsOfFile: path!)
let jsonResult = try? JSONSerialization.jsonObject(with: favoritesList, options: [])
if let array = jsonResult as? [Any] {
if let bookCover = array.first {
bookCoversDisplay = bookCover
} else if let title = array.second {
titlesDisplay = title
} else if let author = array.third {
authorsDisplay = author
} else if let year = array.fourth {
yearDisplay = year
} else if let pages = array.fifth {
pagesDisplay = pages
} else if let starRating = array.sixth {
starRatingDisplay = starRating
} else if let reviews = array.seventh {
reviewsDisplay = reviews
} else if let description = array.eighth {
descriptionsDisplay = description
}
}

maybe can help you:
do{
let data = try Data.init(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "Info", ofType: "json")!))
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(json)
}catch{
print(error)
}

Related

saving json data in coredata in swift

I am trying to save json data which is present in my app bundle. But instead of saving all data it is saving only one data
func getDignosysListFromJson() {
let coreData = CoreDataStack()
let managedObjectContext = coreData.persistentContainer.viewContext
let dignose = Dignose(context: managedObjectContext)
let jsonPath = Bundle.main.path(forResource: "dignosys", ofType: "json")
let jsonUrl = URL(fileURLWithPath: jsonPath!)
do {
let data = try Data(contentsOf: jsonUrl)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
if let newResult = jsonResult as? Array<Dictionary<String, Any>>{
for i in newResult{
let newName = i["dx description"] as! String
print(newName)
dignose.name = newName
dignose.date = "29 Dec 2020"
}
coreData.saveContext()
}
} catch {
print("")
}
}
My json structure is:-
[
{"dx type":"what is foot issue","dx description":"Hereditary motor and sensory neuropathy"},
{"dx type":"what is foot issue","dx description":"Multiple sclerosis"},
{"dx type":"use as secondary when only have issue one side","dx description":"gait instabilityā€¯}
]
Move the line
let dignose = Dignose(context: managedObjectContext)
into the loop
for i in newResult {
let dignose = Dignose(context: managedObjectContext)
let newName = i["dx description"] as! String
print(newName)
dignose.name = newName
dignose.date = "29 Dec 2020"
}
to get a new instance in each iteration.
The code contains a few questionable practices. I recommend this
func getDignosysListFromJson() {
let coreData = CoreDataStack()
let managedObjectContext = coreData.persistentContainer.viewContext
let jsonUrl = Bundle.main.url(forResource: "dignosys", withExtension: "json")!
do {
let data = try Data(contentsOf: jsonUrl)
if let jsonResult = try JSONSerialization.jsonObject(with: data) as? [[String:Any]] {
for anItem in jsonResult {
let dignose = Dignose(context: managedObjectContext)
let newName = anItem["dx description"] as! String
print(newName)
dignose.name = newName
dignose.date = "29 Dec 2020"
}
coreData.saveContext()
}
} catch {
print(error)
}
}

swift how to add dictionary keys values in array

I am working on swift json Parsing where i am recieving json Data from Rest API for eg:
{"baseUrl":"http:\/\/localhost:9010\/",
"pluginOptions":{"values":[{"StartSyncTime":"2020-10-06 17:22:34","uuid":"977a5d03-2cdf-4008-87e6-01594e4369ef","LastSyncTime":"2020-10-06",
"MessageWrapper":{"Routing":"OriginSession","SourceSystem":"Mobile","MessageId":"51152ccd-32c6-475b-86a6-a2c883d551f5",
"UserID":"77ee794e-433d-4b93-bcaa-53408ede50fd","TenantID":"null","TenantName":"visurtest","Payload":"{}",
"DataType":"SQLLiteDDLAsync","MessageKind":"READ"}}],
"database":"structionDB","encrypted":false,"mode":"no-encryption"}}
I am getting as type [String:Any?] from rest api in below code
var pluginOptions : [String: Any]? = call.getObject("pluginOptions")
pluginOptions?[MessageWrapperKeys.DataType] = [DataTypes.SQLLiteDDLAsync]
pluginOptions?[MessageWrapperKeys.MessageKind] = [MessageKinds.READ]
pluginOptions?[MessageWrapperKeys.Payload] = ["{}"]
from above Json Response i need to extract MessageWrapper Dictionary like below
{"Routing":"OriginSession","SourceSystem":"VisurMobile","MessageId":"51152ccd-32c6-475b-86a6-a2c883d551f5",
"UserID":"77ee794e-433d-4b93-bcaa-53408ede50fd","TenantID":"null","TenantName":"visurtest","Payload":"{}",
"DataType":"SQLLiteDDLAsync","MessageKind":"READ"}
where above last 3 key vale i have added from code,Now i have to send Rest Api Call with above request but i did not able to figure it out how i will extraxt MessageWrapper Keys and append above 3 Key Values so that i get final jsonString Request like
{"Routing":"OriginSession","SourceSystem":"Mobile","MessageId":"05086b82-3623-492b-926a-d3bb8d01aa52","UserID":"77ee794e-433d-4b93-bcaa-53408ede50fd","TenantID":"null","TenantName":"test","Payload":"{}","DataType":"SQLLiteDDLAsync","MessageKind":"READ"}
below code i have triyed but not able to access
func readTableFromBackend(_ call: CAPPluginCall) -> Observable<String>{
var swrapper: [[String: Any]] = [[:]]
var pluginOptions : [String: Any]? = call.getObject("pluginOptions")
let json = JSON(pluginOptions)
var arrayNames = json["values"].arrayValue.map {$0["MessageWrapper"].string}
for arrayvalues in json["values"].arrayValue{
for arrayvalues in json["MessageWrapper"].arrayValue{
var string = arrayvalues["UserID"].string
}
var string = arrayvalues["MessageWrapper"].string
print(string)
}
pluginOptions?[MessageWrapperKeys.DataType] = [DataTypes.SQLLiteDDLAsync]
pluginOptions?[MessageWrapperKeys.MessageKind] = [MessageKinds.READ]
pluginOptions?[MessageWrapperKeys.Payload] = ["{}"]
var values = pluginOptions?["values"]
var modes = pluginOptions?["mode"]
for (key,value)in pluginOptions ?? ["":""]{
print("\(key) -> \(value)")
}
var finajsonstring: String = ""
var pluginOptions1: [String:Any] = [MessageWrapperKeys.DataType:DataTypes.SQLLiteDDLAsync, MessageWrapperKeys.MessageKind:MessageKinds.READ,MessageWrapperKeys.Payload: "{}"]
swrapper.append(pluginOptions ?? ["":""])
swrapper.append(pluginOptions1 )
let apidata = PullBackendData()
let plugindata = PluginCallParameterOptions()
var url: String? = call.getString("baseUrl")
// let payload = swrapper
let address = plugindata.getApiUrl(controllerName: Controllers.DataSync, baseUrl: url ?? "")
let jsonData = try? JSONSerialization.data(withJSONObject: pluginOptions)
guard let jsonString = String(data : jsonData!, encoding: .utf8
) else { return Observable.just("Error")}
let data = Data(jsonString.utf8)
do{
let newdata : NSDictionary = try JSONSerialization.jsonObject(with: data, options: []) as! NSDictionary
}
if((newdata.value(forKey: "values")) != nil){
let info : NSArray = newdata.value(forKey: "values") as! NSArray
let info1 : NSArray = info.value(forKey: "MessageWrapper") as! NSArray
var wrapperarray: [[String:Any]] = [[String:Any]]()
wrapperarray = newdata.value(forKey: "values") as! [[String:Any]]
wrapperarray.append(pluginOptions1)
let jsonData: NSData = try JSONSerialization.data(withJSONObject: info1, options: []) as NSData
let jsonData2: NSData = try JSONSerialization.data(withJSONObject: wrapperarray, options: []) as NSData
do {
var jsonstring = try NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue)! as String
var jsonstring2 = NSString(data: jsonData2 as Data, encoding: String.Encoding.utf8.rawValue)! as String
//getting final string and sending to rest api
finajsonstring = jsonstring2 as String
}catch {
print("error")
}
}
} catch let error as NSError{
print(error)
}
let response = apidata.post(_for: address, bodyData: finajsonstring)
return Observable.from(optional: response)
}

Parsing JSON in Swift and accessing values?

I have successfully parsed JSON for:
birthday = "04/10/1986";
id = 202038339983;
location = {
city = Jupiter;
country = "United States";
state = FL;
};
My question is when part of the JSON is:
submissions = {
data = (
{
"created_time" = "2018-02-16T05:11:56+0000";
id = "131448394823824_167398094382256";
viewer = "Any random string and/or emojis";
},
{
"created_time" = "2018-02-14T23:36:41+0000";
id = "809809871824_8908987486899";
message = "vday \Ud83d\Udda4\U2665\Ufe0f";
});}
How am I supposed to access created_time, id, viewer, and message?
I have been able to print the whole submissions JSON response to the console with this code :
guard let jsonD = responseFromServer as? [String : Any] else {return}
let subs1 = (jsonD["submissions"] as? [String : Any])
let accessSubs1 = theSubs1
guard let parsedPost = theSubs1 else {
return
}
My console will display:
["data": <__NSArrayI 0x6040001a86c0>(
{
"created_time" = "2018-02-16T05:11:56+0000";
id = "131448394823824_167398094382256";
viewer = "Any random string and/or emojis";
},
{
"created_time" = "2018-02-14T23:36:41+0000";
id = "809809871824_8908987486899";
message = "vday \Ud83d\Udda4\U2665\Ufe0f";
})]
My question is how should I parse the JSON so I can access the created_time inside submissions?
Here is the HTTP Request:
struct XClass: RequestProtocol {
var Path = "/User"
var parameters: [String : Any]? = ["stuff": "id, birthday, location, submissions"]
var aToken = aToken.current
var httpMethod: RequestHTTPMethod = .GET
var apiVersion: APIVersion = .defaultVersion
struct Response: ResponseProtocol {
var id = String()
var birthday = String()
var city = String()
var state = String()
var country = String()
var viewSubs = [String : Any]()
init(XResponse: Any?) {
guard let jsonD = XResponse as? [String : Any] else {return}
id = (jsonD["id"] as? String)!
birthday = (jsonD["birthday"] as? String)!
let XArr = (jsonD["location"] as? [String : String])
city = XArr!["city"]!
country = XArr!["country"]!
state = XArr!["state"]!
let subs1 = (jsonD["submissions"] as? [String : Any])
let accessSubs1 = theSubs1
guard let parsedPost = theSubs1 else {
return
}
viewSubs = theSubs1
}}}
func getXData(){
let connection = RequestConnection()
connection.add(XClass()) { response, result in
switch result {
case .success(let response):
print("Request Succeeded: \(response)\n\n\n")
case .failed(let error):
print("Request Failed: \(error)")
}}
connection.start()
}
Create a struct
struct Data: Decodable {
var created_time : String
var id : String
var viewer : String
}
call to the api url from URLSession
guard let url = URL(string: "your api url")
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error.localizedDescription)
} else {
guard let data = data else {return}
var data: [Data]() = JSONDecoder().decode(Data.self, data)
for dat in data{
print(dat.created_time)
print(dat.id)
print(dat.viewer)
}
}
If you are not using Decodable from Swift 4, or still in Swift 3,
then you can specify that the data in "submissions" is an array of dictionaries (double brackets) then you can iterate that.
Change
let subs1 = (jsonD["submissions"] as? [String : Any])
To
let subs1 = (jsonD["submissions"] as? [[String : Any]])
for sub in subs1 {
let time = sub["created_time "] as? [String : Any]
...
}

How to get the multiple data inside the json curly braces? Swift

How to get the multiple data inside the json curly braces in swift3?
Can i use this code to get multiple data? (get "crew_id","crew_name","crew_email")
if let crew = user!["crew"] as? [String:Any], let crewName = crew["crew_name"] as? String {
print(crewName)
JSON
crew ={
"crew_avatar" = "http://ec2-52-221-231-3.ap-southeast-1.compute.amazonaws.com/gv/images/profile_image/Pang_Kang_Ming_916210_0e9.jpg";
"crew_contact" = 0123456789;
"crew_email" = "pang#xover.com.my";
"crew_gender" = Male;
"crew_id" = PP000001;
"crew_name" = "Pang Kang Ming";
"crew_preferred_name" = PKM;
"crew_qrcode" = "images/qrcode/qrcode_085960293a5378a64bec6ebfa3c89bb7.png";
};
message = "Login Sucessfully";
result = success;
Yes you can, just add the values you want to unwrap as below, just be aware that if one of the optional binding does not unwrap, even if others unwrap if statement will not be executed, consider separating the if statements.
Depends on all being returned in the json.
if let crew = user!["crew"] as? [String:Any],
let crewName = crew["crew_name"] as? String,
let crewId = crew["crew_id"] as? String {
print(crewName)
print(crewId)
}
Recommended way, even if some values are not present in the json response, you will be able to get the other values.
if let crew = user!["crew"] as? [String:Any] {
if let crewName = crew["crew_name"] as? String {
print(crewName)
}
if let crewId = crew["crew_id"] as? String {
print(crewId)
}
}
if let file = Bundle.main.url(forResource: "yourJsonFileName", withExtension: "json") {
let data = try Data(contentsOf: file)
let json = try JSONSerialization.jsonObject(with: data, options: [])
let jsonData = json as! [[String:Any]]
DispatchQueue.main.async {
let projectName = jsonData.flatMap { $0["crew_avatar"] as? String }
self.crewAvatarArray = projectName
print(self.crewAvatarArray)
let subTitle = jsonData.flatMap { $0["crew_contact"] as? String }
self.crewContactArray = subTitle
let startDate = jsonData.flatMap { $0["crew_email"] as? String }
self.crewEmailArray = startDate
}
}
Try this code

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)
}
}