Re: Modify JSON in Swift

2015-11-07 Thread Roland King

> On 7 Nov 2015, at 20:48, Roland King  wrote:
> 
> Quincey explained why it doesn’t work, value semantics run deep and 
> consistent in Swift. 
> 
> What you could do if you wanted, after messing with images, put it back into 
> the json dictionary again, after your for var image in .. code
> 
> json[ “images” ] = images
> 
> now you have modified json to have a new images member. 

oh not quite - you’re modifying images too - so you have to replace each image 
in that as well as you go. 

perhaps use one of the array operators which takes an array and returns a new 
array to get new images from old. 
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Modify JSON in Swift

2015-11-07 Thread Roland King
Quincey explained why it doesn’t work, value semantics run deep and consistent 
in Swift. 

What you could do if you wanted, after messing with images, put it back into 
the json dictionary again, after your for var image in .. code

json[ “images” ] = images

now you have modified json to have a new images member. 

> On 7 Nov 2015, at 14:54, Rick Mann  wrote:
> 
> I'm trying to do this, but I can't modify the JSON structure.
> 
> 
> ---
> import Foundation
> 
> let s = "{ \"images\" : [ { \"thumb\" : \"url1\", \"width\" : 10 }, { 
> \"thumb\" : \"url2\", \"width\" : 20 } ] }"
> let data = (s as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
> 
> do
> {
>   if var json = try NSJSONSerialization.JSONObjectWithData(data, options: 
> .MutableContainers) as? [String:AnyObject]
>   {
>   print("JSON: \(json)")
>   if var images = json["images"] as? [[String:AnyObject]]
>   {
>   for var image in images
>   {
>   if let thumbURL = image["thumb"]
>   {
>   image["thumb"] = "FOOBAR: \(thumbURL)"
>   print("new: \(image["thumb"])")
>   }
>   }
>   
>   let newData = try 
> NSJSONSerialization.dataWithJSONObject(json, options: 
> NSJSONWritingOptions(rawValue: 0))
>   let s2 = NSString(data: newData, encoding: 
> NSUTF8StringEncoding)
>   print(s2)
>   }
>   }
> }
> 
> catch let e as NSError
> {
>   print("Error parsing model.json: \(e)")
> }
> ---
> JSON: ["images": (
>{
>thumb = url1;
>width = 10;
>},
>{
>thumb = url2;
>width = 20;
>}
> )]
> new: Optional(FOOBAR: url1)
> new: Optional(FOOBAR: url2)
> Optional({"images":[{"thumb":"url1","width":10},{"thumb":"url2","width":20}]})
> ---
> 
> But it seems the way I drill down into the initial json dictionary gives me 
> copies, or otherwise prevents me from modifying the dictionary like this.
> 
> Any suggestions on what I can do? I really don't want to have to walk and 
> rebuild the JSON myself.
> 
> -- 
> Rick Mann
> rm...@latencyzero.com
> 
> 
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/rols%40rols.org
> 
> This email sent to r...@rols.org


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Modify JSON in Swift

2015-11-06 Thread Quincey Morris
On Nov 6, 2015, at 22:54 , Rick Mann  wrote:
> 
> if var images = json["images"] as? [[String:AnyObject]]

No, that won’t work because Swift dictionaries have *value* semantics, so 
you’re *asking* for a copy here. The same thing in Obj-C works because the 
variable ‘images’ would be a reference.

One possible solution would be to change this:

>   if var json = try NSJSONSerialization.JSONObjectWithData(data, options: 
> .MutableContainers) as? [String:AnyObject]

to this:

>   if var json = try NSJSONSerialization.JSONObjectWithData(data, options: 
> .MutableContainers) as? NSMutableDictionary


and stick to the realm of NS collection classes, but it’s pretty ugly.

The other issue you have to be careful of is that casting a NSDictionary to 
(say) ‘[String: AnyObject]’ is probably going to copy the dictionary (to a real 
Dictionary) anyway, because this is a conversion (i.e. copy) cast, not a pure 
bridging cast. The only cast (AFAIK) from an object that’s a NSDictionary to 
Dictionary *without* a conversion is ‘[NSObject: AnyObject]’.

This particular case, of working with Obj-C-derived NSJSONSerialization JSON 
objects in Swift, is actually really really hard. If the structure of the JSON 
object is fixed, it’s probably easier to define a Swift struct for it (or 
rather, a hierarchy of nested structs, dictionaries and arrays), and populate 
it once at the start and reconstruct the serialization dictionary at the end.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com