簡體   English   中英

如何解析NSDictionary數據

[英]How to parse NSDictionary Data

我的應用程序當前正在使用Yelp服務API,並返回yelp客戶端提供的關聯數據的鍵值對。 我的情況是,我有一個景點視圖控制器,其中放置了不同類別的圖釘注釋,例如“亞洲食品”等。當您單擊圖釘注釋並單擊標注時,它將帶您到詳細視圖控制器。

這是我要做的:

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

這是我的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)
        }
    }

當我在西雅圖地區查詢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";
    }

我想做的就是簡單地提取yelp響應數據,並將我在DetailViewController中擁有的AddressLabel文本設置為Yelp數據中的地址(因為reverseGeoCoding有一些小錯誤)。

目前,我正在使用我創建的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 ""
    }
}

謝謝!

新答案

因為您使用的是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"
}

您可能可以根據自己的需要來重新格式化注釋的外觀。

關於此的更多信息,以及本機快速嵌套字典訪問,可以在我剛剛看過的這篇很有幫助的文章中找到。

原始答案

如果我正確理解了您的問題,並且假設YelpBusiness對象與我在此github存儲庫中看到的內容匹配,那么您所需要做的就像更改此行一樣簡單:

annotation.title = yelpBusinessMock.name

至:

annotation.title = yelpBusinessMock.location.display_address

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM