简体   繁体   English

如何解析NSDictionary数据

[英]How to parse NSDictionary Data

My app currently is using Yelp Service API and returns key value pairs of associated data that the yelp client provides. 我的应用程序当前正在使用Yelp服务API,并返回yelp客户端提供的关联数据的键值对。 My scenario is that I have an Attractions view controller which drops pin annotations of different categories, ie 'Asian Food', etc. When you click on the pin annotation and hit the callout it takes you to a Detail View Controller. 我的情况是,我有一个景点视图控制器,其中放置了不同类别的图钉注释,例如“亚洲食品”等。当您单击图钉注释并单击标注时,它将带您到详细视图控制器。

Here is where I do that: 这是我要做的:

func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
        if (control == view.rightCalloutAccessoryView) {
            let selectedLocation = view.annotation;
            let selectedCoordinate = view.annotation.coordinate;
            var latitude = selectedCoordinate.latitude
            var longitude = selectedCoordinate.longitude
            var location:CLLocation = CLLocation(latitude: latitude, longitude: longitude)
            let businessPlacemark = MKPlacemark(coordinate: selectedCoordinate, addressDictionary: nil)
            indicatedMapItem = selectedCoordinate;
            performSegueWithIdentifier("attractionToDetail", sender: self);
        }
    }
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var attractionsDetailViewController:AttractionsDetailViewController = segue.destinationViewController as! AttractionsDetailViewController
        attractionsDetailViewController.attractionLocation = indicatedMapItem;
    }

And here is my API service call: 这是我的API服务调用:

class func searchWithQueryWithRadius(map: MKMapView, term: String, deal: Bool, radius: Int, sort: Int, categories: String, completion: ([Resturant]!, NSError!) -> Void) {
        YelpClient.sharedInstance.searchWithTerm(term, deal: false, radius: radius, sort: sort,categories: categories, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
            let responseInfo = response as! NSDictionary
            resultQueryDictionary = responseInfo
            println(responseInfo)
            let dataArray = responseInfo["businesses"] as! NSArray
            for business in dataArray {
                let obj = business as! NSDictionary
                var yelpBusinessMock: YelpBusiness = YelpBusiness(dictionary: obj)
                var annotation = MKPointAnnotation()
                annotation.coordinate = yelpBusinessMock.location.coordinate
                annotation.title = yelpBusinessMock.name
                map.addAnnotation(annotation)
            }
            }) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
            println(error)
        }
    }

This prints to the logs data like this when I query for Asian Food in the Seattle area: 当我在西雅图地区查询Asian Food时,将这样打印到日志数据:

{
businesses =     (
            {
        categories =             (
                            (
                Korean,
                korean
            ),
                            (
                Buffets,
                buffets
            )
        );
        "display_phone" = "+1-206-854-3166";
        distance = "124.9692597772704";
        id = "ummas-lunch-box-seattle";
        "image_url" = "http://s3-media2.fl.yelpcdn.com/bphoto/QqrpImnPywZ9zc721RVRrg/ms.jpg";
        "is_claimed" = 1;
        "is_closed" = 0;
        location =             {
            address =                 (
                "1301 5th Ave",
                Concourse
            );
            city = Seattle;
            coordinate =                 {
                latitude = "47.6088937";
                longitude = "-122.3342613";
            };
            "country_code" = US;
            "cross_streets" = "Union St & University St";
            "display_address" =                 (
                "1301 5th Ave",
                Concourse,
                Downtown,
                "Seattle, WA 98101"
            );
            "geo_accuracy" = "9.5";
            neighborhoods =                 (
                Downtown
            );
            "postal_code" = 98101;
            "state_code" = WA;
        };
        "mobile_url" = "http://m.yelp.com/biz/ummas-lunch-box-seattle";
        name = "Umma's Lunch Box";
        phone = 2068543166;
        rating = "4.5";
        "rating_img_url" = "http://s3-media2.fl.yelpcdn.com/assets/2/www/img/99493c12711e/ico/stars/v1/stars_4_half.png";
        "rating_img_url_large" = "http://s3-media4.fl.yelpcdn.com/assets/2/www/img/9f83790ff7f6/ico/stars/v1/stars_large_4_half.png";
        "rating_img_url_small" = "http://s3-media2.fl.yelpcdn.com/assets/2/www/img/a5221e66bc70/ico/stars/v1/stars_small_4_half.png";
        "review_count" = 155;
        "snippet_image_url" = "http://s3-media1.fl.yelpcdn.com/photo/H1UEaGpAztTzFIDKbsx_UA/ms.jpg";
        "snippet_text" = "Korean comfort food at an affordable price. My only wish is that they are opened longer..\n\nI'm sure that everybody here has already written about it, but it...";
        url = "http://www.yelp.com/biz/ummas-lunch-box-seattle";
    }

What I want to do is simply extract the yelp response data and set the AddressLabel text I have in my DetailViewController to the address from the Yelp Data(As reverseGeoCoding has minor bugs). 我想做的就是简单地提取yelp响应数据,并将我在DetailViewController中拥有的AddressLabel文本设置为Yelp数据中的地址(因为reverseGeoCoding有一些小错误)。

Currently i'm using this YelpBusiness.swift that I created, but i'm not sure if it's correct... 目前,我正在使用我创建的YelpBusiness.swift,但不确定是否正确...

var dictionary: NSDictionary


init(dictionary: NSDictionary) {
    self.dictionary = dictionary
}

var business: String {
    get {
        return self.dictionary["businesses"] as! String
    }
}

var name: String {
    get {
        return self.dictionary["name"] as! String
    }
}

var phone: String {
    get {
        return self.dictionary["phone"] as! String
    }
}

var rating: String {
    get {
        return self.dictionary["rating"] as! String
    }
}

var imageURL: NSURL? {
    get {
        if let image = self.dictionary["image_url"] as? String {
            return NSURL(string: image.stringByReplacingOccurrencesOfString("ms.jpg", withString: "ls.jpg", options: nil, range: nil))
        }
        return nil
    }
}

var ratingImageURL: NSURL {
    get {
        return NSURL(string: self.dictionary["rating_img_url_large"] as! String)!
    }
}

var reviewCount: Int {
    get {
        return self.dictionary["review_count"] as! Int
    }
}

var deals: Array<AnyObject>? {
    get {
        if let deals = self.dictionary["deals"] as? Array<AnyObject> {
            return deals
        }
        return nil
    }
}

var latitude: Double? {
    get {
        if let location = self.dictionary["location"] as? NSDictionary {
            if let coordinate = location["coordinate"] as? NSDictionary {
                return (coordinate["latitude"] as! Double)
            }
        }
        return nil
    }
}

var longitude: Double? {
    get {
        if let location = self.dictionary["location"] as? NSDictionary {
            if let coordinate = location["coordinate"] as? NSDictionary {
                return (coordinate["longitude"] as! Double)
            }
        }
        return nil
    }
}

var location: CLLocation {
    get {
        return CLLocation(latitude: self.latitude!, longitude: self.longitude!)
    }
}

var shortAddress: String {
    get {
        if let location = self.dictionary["location"] as? NSDictionary {
            if let address = location["address"] as? Array<String> {
                if let neighborhoods = location["neighborhoods"] as? Array<String> {
                    return ", ".join(address + [neighborhoods[0]])
                }
                return ", ".join(address)
            }
        }
        return ""
    }
}

var displayAddress: String {
    get {
        if let location = self.dictionary["location"] as? NSDictionary {
            if let address = location["display_address"] as? Array<String> {
                return ", ".join(address)
            }
        }
        return ""
    }
}

var displayCategories: String {
    get {
        if let categories = self.dictionary["categories"] as? Array<Array<String>> {
            return ", ".join(categories.map({ $0[0] }))
        }
        return ""
    }
}

Thanks! 谢谢!

NEW ANSWER 新答案

Because you're using NSDictionary & NSArray objects, you can use the magical valueForKeyPath: 因为您使用的是NSDictionary和NSArray对象,所以可以使用神奇的valueForKeyPath:

// I HIGHLY recommend a more descriptive variable name instead of "obj"
let obj = business as! NSDictionary 
let displayAddressArray = obj.valueForKeyPath("location.display_address") as NSArray

if displayAddressArray.count > 0
{
    annotation.title = "\(displayAddressArray[0])\n\(displayAddressArray[1])\n"
}

You probably can reformat how the annotation looks depending on what you want it to look like. 您可能可以根据自己的需要来重新格式化注释的外观。

More information about this, plus native swift nested dictionary access, can be found in this helpful article I was just looking at . 关于此的更多信息,以及本机快速嵌套字典访问,可以在我刚刚看过的这篇很有帮助的文章中找到。

ORIGINAL ANSWER 原始答案

If I understand your question correctly, and assuming the YelpBusiness object matches what I see in this github repo , what you need to do might be as easy as something like changing this line: 如果我正确理解了您的问题,并且假设YelpBusiness对象与我在此github存储库中看到的内容匹配,那么您所需要做的就像更改此行一样简单:

annotation.title = yelpBusinessMock.name

to: 至:

annotation.title = yelpBusinessMock.location.display_address

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM