2014-06-08 14 views
7

Tôi đang trong quá trình cố gắng di chuyển một dự án hiện có sang Swift, nhiều bài tập học tập hơn nhưng tôi nghĩ rằng tôi đã gặp phải vấn đề nghĩ rằng nó có thể liên quan đến sự thiếu hiểu biết của tôi về AnyObject.Không thể downcast từ 'AnyObject' trong khi phân tích cú pháp mảng JSON

tôi đã tạo ra một đối tượng bao gồm một số biến và được khởi tạo như:

var customObject:MycustomObject = MYcustomObject() 

tôi sau đó sử dụng NSURLConnection để lấy dữ liệu JSON và điều này tất cả dường như được làm việc một cách chính xác như jsonArray đang được dân cư với dữ liệu

jsonArray = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSArray 

tôi sau đó lặp qua mảng và cố gắng để phân tích dữ liệu và đây là nơi tôi đang gặp vấn đề này, cho giá trị mặc định vòng lặp chi tiết để AnyObject.

for details:AnyObject in jsonArray { 
    parseDetail(details as NSDictionary) 
} 

Vấn đề liên quan đến integerValue, nó tạo ra một "có thể không nhìn xuống từ 'AnyObject' để không @ objc ...." lỗi

func parseDetail(element: NSDictionary) { 
     self.customObject.stringValue  = element["id"] as String 
     self.customObject.integerValue  = element["type"] as Integer 
} 

Ngoài ra còn có vẻ là một số khác biệt trong cách NSString & Chuỗi đang hoạt động, sự hiểu biết của tôi cho đến nay là khi sử dụng Swift tôi nên sử dụng kiểu gốc Sting, Float Integer v.v. Nếu tôi sử dụng NSString chuỗiValue hiển thị chính xác trong cửa sổ gỡ lỗi nhưng khi sử dụng kiểu String I nhận được các thông tin sau:

{ 
    core = { 
    _baseAddress = Builtin.RawPointer = 0x0b227f49 
    _countAndFlags = 1073741828 
    _owner = Some { 
     Some = (instance_type = Builtin.RawPointer = 0x0b227f40 -> 0x006d58f0 (void *)0x006d58c8:   __NSCFString) 
    } 
    } 
} 

Xin lỗi, đây là một chút dài nhưng có bất kỳ thông tin nào về luồng không, đây là thử thách tiếp theo của tôi không?

NSThread.detachNewThreadSelector(Selector: parseDetail(), toTarget: self, withObject: nil) 
+0

tại sao bạn sử dụng một nsarry thay vì một mảng nhanh? – connor

+0

Bạn đã cố gắng không chỉ định loại trong vòng lặp? (I E., 'Để biết chi tiết trong jsonArray') – Jiaaro

+0

Một câu trả lời cho câu hỏi đầu tiên của bạn cũng được bảo hiểm tại bài viết này: [Làm việc với dữ liệu Cocoa loại - Mảng] (https://developer.apple.com/library/prerelease/ios/documentation/ Swift/Khái niệm/BuildingCocoaApps/WorkingWithCocoaDataTypes.html) đối với câu hỏi thứ hai, [tìm kiếm] (https://developer.apple.com/library/prerelease/ios/search/?q=detachNewThreadSelector) cho thấy không chỉ tài liệu liên quan nhưng cũng mẫu ứng dụng sử dụng phương pháp này. –

Trả lời

10

Dưới đây là một ví dụ nhỏ thực hiện công việc. Thứ nhất, đây là một lớp mô hình cho các mục đích của chúng tôi:

class CustomObject { 
    var name: String = "" 
    var age : Int = 0 

    init(json: Dictionary<String, AnyObject>) { 
     name = json["name"] as NSString 
     age = (json["age" ] as NSNumber).integerValue 
    } 
} 

Như bạn có thể thấy, chúng ta vẫn cần phải đối phó với NSNumbers và NSStrings từ NSJSONSerialization chưa được cập nhật cho các loại Swift.

Tiếp theo, một chút tập tin json.txt cư trú tại dự án của chúng tôi:

[{"name":"Alice","age":30},{"name":"Bob","age":40}] 

Và cuối cùng, phân tích cú pháp, ngay trong mắt ứng dụng cho một thử nghiệm nhanh:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { 
    var filePath = NSBundle.mainBundle().pathForResource("json", ofType:"txt") 
    var data  = NSData(contentsOfFile:filePath) 
    var json  = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as Array<Dictionary<String, AnyObject>> 

    var customObjects = json.map { dict in CustomObject(json: dict) } 

    println(customObjects[0].name) 
    println(customObjects[0].age) 

    return true 
} 

này sẽ in:

Alice 
30 
+0

Tại sao bạn sử dụng tùy chọn MutableContainers? – joerick

+1

@Hãy cố gắng tuân thủ ý định của OP. –

0

Cập nhật tiến trình, các mục sau là chính xác và đang hoạt động:

.interegervalue 
.doublevalue 
.boolvalue 

Lý do tại sao ở trên xuất hiện không hoạt động là dữ liệu JSON đã thay đổi và một số yếu tố không còn tồn tại nữa. Vì vậy, phần tử ["type"] không tồn tại, bằng cách sử dụng Swift kết quả này trong một vụ tai nạn trong khi trong Objective-C không có tai nạn xảy ra.

Tất cả các phần của quá trình học tập ..

+0

Nó bị treo vì truy cập phần tử của từ điển bằng cách sử dụng chỉ số con trả về một giá trị tùy chọn. Bạn có lẽ sẽ muốn làm như sau để bảo vệ đối với trường hợp các dữ liệu JSON không chứa một phím đặc biệt: 'code' nếu chúng ta hãy id = element [ "id"] như? Chuỗi { self.customObject.stringValue = id } – mbeaty

Các vấn đề liên quan