NSJSONSerialization not working as expected in a Playground
In order to use asynchronous operations in an Xcode Playground, you need to set needsIndefiniteExecution
to true
.
Add this at the top of your code:
Swift 2
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
Swift 3
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
NSJSONSerialization, NSURLSession, Unicode in application/json responses
Actually the unicode for is \u1F4A9
, try this in a playground:
print("\u{1f4a9}")
print("\u{f4a9}")
NSJSONSerialization with small decimal numbers
For precise base-10 arithmetic (up to 38 significant digits)
you can use NSDecimalNumber
:
let jsonInput = [ "value": NSDecimalNumber(string: "0.81") ]
or
let val = NSDecimalNumber(integer: 81).decimalNumberByDividingBy(NSDecimalNumber(integer: 100))
let jsonInput = [ "value": val ]
Then
let data = try NSJSONSerialization.dataWithJSONObject(jsonInput, options: NSJSONWritingOptions.PrettyPrinted)
let json = NSString(data: data, encoding: NSUTF8StringEncoding)!
print( json )
produces the output
{
"value" : 0.81
}
json manipulation in swift, cant get the data
I only had a look at the last part of your code, the one relevant to your question, and what I saw was that you should really use safe unwrapping.
I made your code work just by getting rid of all the force unwrapping with !
and replacing it with safe optional binding.
Also, deviceList
is an array, not a dictionary.
So, after the line let data = json1.dataUsingEncoding.....
, replace everything with this and it will work:
if let json6 = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject] {
if let innerJSON = json6["json"] as? [String: AnyObject], let deviceList = innerJSON["deviceList"] as? [[String: AnyObject]] {
for device in deviceList {
print(device["IP"])
}
}
}
The idea is to cast the objects to their right type with optional binding: json6
is a dictionary, its "json" key has a dictionary for value, and the "deviceList" key of this dictionary contains an array of dictionaries containing IPs.
Note that your JSON data seems to contain errors. The 'IP' field contains the string "String", I'm not sure this is what you expect...
Swift Error: Statements are not allowed at the top level
Because it is a snippet. You are expected to use it inside a function, where it is legal. Executable code can appear only in a function.
How do I deserialize a JSON string into an NSDictionary? (For iOS 5+)
It looks like you are passing an NSString
parameter where you should be passing an NSData
parameter:
NSError *jsonError;
NSData *objectData = [@"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
Why GCD dispatch group notify is not called in Playground and Unit tests
Thanks for the idea to @paulvs, and to this post, here's the code needed for unit tests:
let service = MyService()
let expect = expectation(description: "longRunningFunction")
service.loadList {
expect.fulfill()
}
self.waitForExpectations(timeout: 0.5) { error in
XCTAssert(service.isLoaded, "Not loaded")
}
How to write NSData to a new file in Swift?
Your code is correct, but the file is not being written where you expect. Swift Playgrounds are sandboxed and the files are in another part of the system, not in your project's resources folder.
You can check that the file is actually being saved by immediately trying to read from it, like so:
let validDictionary = [
"numericalValue": 1,
"stringValue": "JSON",
"arrayValue": [0, 1, 2, 3, 4, 5]
]
let rawData: NSData!
if NSJSONSerialization.isValidJSONObject(validDictionary) { // True
do {
rawData = try NSJSONSerialization.dataWithJSONObject(validDictionary, options: .PrettyPrinted)
try rawData.writeToFile("newdata.json", options: .DataWritingAtomic)
var jsonData = NSData(contentsOfFile: "newdata.json")
var jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: .MutableContainers)
// -> ["stringValue": "JSON", "arrayValue": [0, 1, 2, 3, 4, 5], "numericalValue": 1]
} catch {
// Handle Error
}
}
From Tom's comment below: Specifically, the file is in some place like /private/var/folders/bc/lgy7c6tj6pjb6cx0p108v7cc0000gp/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.MyPlayground-105DE0AC-D5EF-46C7-B4F7-B33D8648FD50/newdata.json.
Related Topics
How to Trigger an Action When a Swiftui Toggle() Is Toggled
How to Create Uicollectionviewcell Programmatically
How to Get the Current Queue Name in Swift 3
iOS 11 Large Title Navigation Bar Snaps Instead of Smooth Transition
Access Static Variables Within Class in Swift
Swift: How to Reload Row Height in Uitableviewcell Without Reloading Data
Swift Convert Time to Time Ago
Save Avcapturevideodataoutput to Movie File Using Avassetwriter in Swift
Does Swift Compile to Native Code
How to Make a Swift Enum with Associated Values Equatable
How to Change the Z Index or Stack Order of Uiview
Swift, How to Implement Hashable Protocol Based on Object Reference
Fill Circle with Wave Animation in Swiftui
Differencebetween Final Class and Class