I am try to convert this JSON data into Dictionary, but I don't know how the data will be structured in this JSON. I think my code for detect JSON struct thats wrong.
JSON Response
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 2,
"id": 2,
"title": "et ea vero quia laudantium autem",
"body": "delectus reiciendis molestiae occaecati non minima eveniet qui voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui incidunt\nut animi commodi"
}
]
Thats my code :
enum postResult {
case Success([Post]) //return array of post
case Failure(ErrorType)
//
func postsFromJSONData(data:NSData)->PhotosResult{
do {
let jsonObject : AnyObject = try NSJSONSerialization.JSONObjectWithData(data,options:[])
guard let jsonDictionary = jsonObject as? [NSObject:AnyObject],
postsArray = ["userId"] as? [[String:AnyObject]] else {
return.Failure(InvalidError.InvalidJSONData)
}
var finalPosts = [post]()
return.Success(finalPosts)
}
catch let error {
return.Failure(error)
}
}
}
Your response is Array not Dictionary, so you need to access object from Array also your userId key contains number as value not Array/Dictionary.
let jsonObject = tryNSJSONSerialization.JSONObjectWithData(data,options:[]) as! [[String: AnyObject]]
if jsonObject.count > 0 {
if let userId = jsonObject[0]["userId"] as? Int {
print(userId)
}
}
Related
I am having some issues with the textfield not moving up with the view.
I am using a textfield with Vertical axis (iOS 16) to create the multiline. This works correctly and stays above the keyboard as expected when it is not embedded in a scrollview. But as soon as the textfield is embedded in the scrollview the multiline just goes below the keyboard and you have to manually scroll to see the last line.
Please see code below. This should work correctly. But if you remove the scrollview you will notice the issue when typing.
struct ContentView: View {
#State private var text = "Lorem ipsum dolor sit amet. Nam voluptatem necessitatibus aut quis odio rem error repudiandae id aliquam perferendis et quidem quaerat et enim harum! Cum nesciunt animi rem quia vero aut omnis eligendi in ducimus eaque sit mollitia fugit est animi nesciunt. Ut exercitationem nulla qui dolor nihil ad autem vero quo internos sapiente eum dicta nihil qui exercitationem cumque et consectetur dolore. Et fugiat officiis non harum voluptas et modi repellendus ut repellat dolorem 33 eveniet quidem qui galisum veritatis. Id consequatur tenetur et eaque voluptas in assumenda delectus et fuga praesentium rem provident delectus est necessitatibus sunt quo dignissimos dolorum. Et reiciendis error et rerum eligendi qui illum error? In soluta ipsum est molestiae pariatur hic voluptas animi qui cupiditate amet."
var body: some View {
ScrollView {
VStack() {
TextField("Enter something", text: $text, axis: .vertical)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
}
}
If there are any GitHub repos you know that would also be great.
Update:
I have found a solution and will be posting it in the coming days.
This is not a definitive answer. In the simulator some buggy behavior appears. Try this out and see on a real device (that I don't have here).
import SwiftUI
struct ContentView: View {
#State private var text = "Lorem ipsum dolor sit amet. Nam voluptatem necessitatibus aut quis odio rem error repudiandae id aliquam perferendis et quidem quaerat et enim harum! Cum nesciunt animi rem quia vero aut omnis eligendi in ducimus eaque sit mollitia fugit est animi nesciunt. Ut exercitationem nulla qui dolor nihil ad autem vero quo internos sapiente eum dicta nihil qui exercitationem cumque et consectetur dolore. Et fugiat officiis non harum voluptas et modi repellendus ut repellat dolorem 33 eveniet quidem qui galisum veritatis. Id consequatur tenetur et eaque voluptas in assumenda delectus et fuga praesentium rem provident delectus est necessitatibus sunt quo dignissimos dolorum. Et reiciendis error et rerum eligendi qui illum error? In soluta ipsum est molestiae pariatur hic voluptas animi qui cupiditate amet."
#Namespace var bottomText
var body: some View {
ScrollViewReader { proxy in
ScrollView {
Text("Title")
.font(.largeTitle)
TextField("Enter something", text: $text, axis: .vertical)
.textFieldStyle(RoundedBorderTextFieldStyle())
.onChange(of: text) { newValue in
print("Fired.")
withAnimation {
proxy.scrollTo(bottomText, anchor: .center)
}
}
Color.red.frame(height: 50).id(bottomText)
}
}
}
}
When TextField axis is .vertical, anchor must be .top
VStack {
// ... other code
.onSubmit {
// update state here !!
if (i + 1) < inputsValues.count {
focusedInput = i + 1
} else {
focusedInput = nil
}
}
}
.onChange(of: focusedInput) {
// When TextField axis is .vertical, anchor must be .top
proxy.scrollTo($0, anchor: .top)
}
Here is full source code.
I am trying to add all elements to a list, Here is my code the code below will run in dart pad.
void main() {
mydates();
}
class Event {
const Event(this.date, this.title, this.description);
final DateTime date;
final String title;
final String description;
#override
String toString() => title;
}
List<Event> eventList = [
Event(DateTime(2021, 1, 1), "Buy milk",
"Lorem ipsum dolor sit amet, consectetur adipiscingelit. Pellentesque sem"),
Event(DateTime(2021, 1, 1), "Go to gym",
"Duis congue enim ut justo interdum, id porta turpisvarius"),
Event(DateTime(2021, 1, 2), "Running",
"Fusce in varius lorem. Praesent accumsan metus at semfaucibus"),
];
//Function
mydates() {
var eventDayMap = <DateTime, List<Event>>{};
for (var event in eventList) {
print(event.date); // Prints each element in the List<Event>
print(event.title);
print(event.description);
// Adding them to the eventDayMap
// Creates a new list
// Adds only the date and title
(eventDayMap[event.date] ??= []).add(event);
}
print(eventDayMap);
//print(eventDayMap.runtimeType);
return eventDayMap;
}
What is returned is this
{2021-01-01 00:00:00.000: [Buy milk, Go to gym], 2021-01-02 00:00:00.000: [Running]}
What I'm trying to achieve is the {date, title, description} and there can be many title and descriptions for one date.
{2021-01-01 00:00:00.000: [Buy milk, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem ],
[Go to gym, Duis congue enim ut justo interdum, id porta turpis varius],
2021-01-02 00:00:00.000: [Running, Fusce in varius lorem. Praesent accumsan metus at sem faucibus]}
So I can have a title and a description returned.
Thanks for any guidance.
What your problem is depends on what your goal is.
If you want to create a valid JSON map, you will want to represent each element by a list. That doesn't appear to be the case since your keys are DateTime objects, not strings.
If you just want to be able to print the events, for debugging, then your problem is the String toString() => title; declaration.
Your map is fine, it maps from dates to Event objects. That's what you'll want.
Then you try to print that map, which calls toString on each value, which only returns the title string.
That only matters if you actually print the map, which you shouldn't be doing (except for debugging).
If you change toString to
String toString() => "[$title, $description]";
you'll likely get what it appears you're looking for.
I think I worked it out after a long time trying to do it my self it comes to me after posting it here.
I needed to return a List instead of a single event.
void main() {
mydates();
}
class Event {
const Event(this.date, this.title /*, this.description*/);
final DateTime date;
final List title;
//final String description;
//#override
//String toString() => title;
}
List<Event> eventList = [
Event(DateTime(2021, 1, 1), [
"Buy milk",
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem"
]),
Event(DateTime(2021, 1, 1), [
"Go to gym",
"Duis congue enim ut justo interdum, id porta turpis varius"
]),
Event(DateTime(2021, 1, 2), [
"Running",
"Fusce in varius lorem. Praesent accumsan metus at sem faucibus"
]),
];
//Function
mydates() {
var eventDayMap = <DateTime, List<Event>>{};
for (var event in eventList) {
print(event.date); // Prints each element in the List<Event>
print(event.title);
//print(event.description);
// Adding them to the eventDayMap
// Creates a new list
// Adds only the date and title
(eventDayMap[event.date] ??= []).add(event);
}
print(eventDayMap);
//print(eventDayMap.runtimeType);
return eventDayMap;
}
Now it returns
2021-01-01 00:00:00.000
[Buy milk, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sem]
2021-01-01 00:00:00.000
[Go to gym, Duis congue enim ut justo interdum, id porta turpis varius]
2021-01-02 00:00:00.000
[Running, Fusce in varius lorem. Praesent accumsan metus at sem faucibus]
Not exactly what I was looking for but it might be a better solution.
I have this json which I converted to a POJO
The JSON converted to POJO file
[
{
"postId": 81,
"id": 401,
"name": "cum voluptate sint voluptas veritatis",
"email": "Vella.Mayer#colten.net",
"body": "sit delectus recusandae qui\net cupiditate sed ipsum culpa et fugiat ab\nillo dignissimos quo est repellat dolorum neque\nvoluptates sed sapiente ab aut rerum enim sint voluptatum"
},
{
"postId": 81,
"id": 403,
"name": "cum voluptate sint voluptas veritatis",
"email": "Vella.Mayer#colten.net",
"body": "sit delectus recusandae qui\net cupiditate sed ipsum culpa et fugiat ab\nillo dignissimos quo est repellat dolorum neque\nvoluptates sed sapiente ab aut rerum enim sint voluptatum"
}
]
This is the POJO class I converted it into
public class TodoItem{
private int id;
private boolean completed;
private String title;
private int userId;
I tried using todo to validate the response that it of the type of the class but always get this error.
Todo todo = response.getBody().as(Todo.class);
Assert.assertTrue(response.statusCode() == 200);
Error
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `io.christdoes.pojo.todo.Todo` out of START_ARRAY token
at [Source: (String)"[
There are 2 things you did wrong:
The POJO that you're matching
The way you map (Array cannot map to one single object)
It would be
List<TodoItem> todoItems = response.as(new TypeRef<>() {});
POJO (I use lombok to generate getters/setters)
import lombok.Data;
#Data
public class TodoItem{
private int postId;
private int id;
private String name;
private String email;
private String body;
}
I have created these typealias in my project
typealias JSON = [String: AnyObject]
typealias JSONArray = [JSON]
I'm testing an JSON API Client using JSONPlaceholder and getting two different JSON responses.
Response 1 (JSON)
{
userId: 1,
id: 1,
title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
}
Response 2 (Array of JSON)
[
{
userId: 1,
id: 1,
title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto"
},
{
userId: 1,
id: 2,
title: "qui est esse",
body: "est rerum tempore vitae sequi sint nihil reprehenderit dolor beatae ea dolores neque fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis qui aperiam non debitis possimus qui neque nisi nulla"
},
...
]
In order to create my code as generic as possible, I'm using a protocol approach. Everything works fine but I have a small issue parsing the json response.
// JSONResource is a protocol
extension JSONResource {
func handleResponse(_ data: Data?, response: URLResponse?, error: NSError?) -> WebServiceResult<Response> {
let parsedData = try! JSONSerialization.jsonObject(with: data, options: .allowFragments)
do {
if let json = parsedData as? JSON {
let parsedResponse = try Response(json: json)
return .success(parsedResponse)
}
if let jsonArray = parsedData as? JSONArray {
let parsedResponse = try Response(jsonArray: jsonArray)
return .success(parsedResponse)
}
} catch let error as NSError {
return .failure(error)
}
}
}
The Response is created using a protocol too
protocol JSONServiceResponse: WebServiceResponse {
init(json: JSON) throws
init(jsonArray: JSONArray) throws
}
My problem is my code seems redundant because I have to handle JSON an JSONArray types but I'll only know that when I'm creating the type who implements the protocol.
Is there a different way to handle the JSON and JSONArray responses from the server in order to use a unique init(json: JSON) ?
Thanks
I am working with this cypher to retrieve nested data for a set of libraries, each having 0-X number of books with each book having 0-X number of authors. The cypher looks like this:
MATCH (library:Library)--(book:Book)--(author:Author)
WITH library, book, {name: author.name} AS nest_author
WITH library, {name: book.name, authors: collect(nest_author)} AS nest_book
WITH {name: library.name, books: collect(nest_book)} AS nest_library
RETURN {library_data: collect(nest_library)}
The only problem with this cypher is that is only works when a library has a book and a book has an author. I tried the query below, but the structure is lost and all the authors appear under all the books and all the books appear under all the libraries:
MATCH (library:Library),(book:Book),(author:Author)
OPTIONAL MATCH (library)--(book)
OPTIONAL MATCH (book)--(author)
WITH library, book, {name: author.name} AS nest_author
WITH library, {name: book.name, authors: collect(nest_author)} AS nest_book
WITH {name: library.name, books: collect(nest_book)} AS nest_library
RETURN {library_data: collect(nest_library)}
How would I write the first query so that the relationships are optional and the collect just returns an empty list when the library doesn't have any books or a book doesn't contain an author?
In your second query you are creating cross products behavior.
Based on the following neo4j console example : http://console.neo4j.org/r/l1cpwz
This query do the trick :
MATCH (n:Library)
OPTIONAL MATCH (n)--(book:Book)
OPTIONAL MATCH (book)--(author:Author)
RETURN n.name, collect({ book: book.title, author: author.lastname })
The example result is the following :
n.name collect({ book: book.title, author: author.lastname })
aspernatur [ {book:"Eligendi fuga est harum est nobis nam id.", author:null}, {book:"Numquam animi ex alias rerum quas.", author:null}]
consectetur [ {book:"Vel nostrum modi officia.", author:null}, {book:"Dolorum dolor optio aut ipsum.", author:null}, {book:"Iste sit quo reprehenderit dolores neque.", author:null}]
corrupti [ {book:"Minus sit sed quia tempora quaerat.", author:null}]
deserunt [ {book:"Temporibus impedit quod aut vel et.", author:null}, {book:"Praesentium perspiciatis blanditiis et omnis suscipit nostrum repudiandae.", author:null}]
labore [ {book:"Non quis maxime doloremque et.", author:null}, {book:"Eos voluptatem voluptatibus mollitia exercitationem nobis.", author:null}, {book:"Vel voluptatem quae libero non est eaque.", author:null}, {book:"Atque velit accusantium perspiciatis assumenda voluptas ea corporis.", author:null}]
nihil [ {book:"Deleniti illo earum eaque sapiente perspiciatis omnis quia.", author:null}, {book:"Est eum enim quo suscipit et molestias.", author:null}, {book:"Consequuntur nam temporibus explicabo quia ipsum.", author:null}, {book:"Facilis ratione illum ipsum sed cum ut.", author:null}, {book:"Est eos quis suscipit ratione alias necessitatibus asperiores sunt.", author:null}, {book:"Odit voluptatem est reiciendis quod tempora.", author:null}]
officiis [ {book:"Ad libero porro quibusdam voluptatum.", author:null}, {book:"Numquam omnis ut unde sequi sint enim.", author:null}]
omnis [ {book:"Qui laboriosam alias repellendus quibusdam incidunt et.", author:null}, {book:"Eos officia vitae consequatur qui.", author:null}, {book:"Explicabo nemo eos maxime.", author:null}, {book:"Dolores voluptatum et similique natus dolore fuga perferendis molestiae.", author:null}, {book:"Quidem aut ut ut quas veritatis.", author:null}, {book:"In in quos et aspernatur dolores.", author:null}, {book:"Alias sed quasi explicabo possimus veniam temporibus.", author:null}, {book:"Omnis dolor eum molestiae veritatis.", author:null}]
tempore [ {book:null, author:null}]