2015-03-25 22 views
13

Tôi đang gặp vấn đề hiệu suất nghiêm trọng phân tích cú pháp JSON với SwiftyJson từ API của chúng tôi và đưa vào các dữ liệu cốt lõi.SwiftyJSON Performance vấn đề

Các dữ liệu sẽ được tải về với Alamofire, mà công trình độc đáo nhưng phân tích cú pháp JSON với SwiftyJson là đau đớn chậm. Để xem nếu thư viện thực sự là vấn đề tôi viết lại phân tích cú pháp json ở một trong nhiều nơi dữ liệu được phân tích cú pháp. Trong đoạn code dưới đây tôi phân tích các giờ mở cửa của một trong khoảng 400 điểm du lịch.

Thấy sự khác biệt trong các ảnh chụp màn hình, 7,7 giây đến 185 ms:

enter image description here

enter image description here

Các Swifty cách:

let openDescription:String = json["OpeningHours"]["OpeningHoursGenericExceptions"].string! 
    let monOpen:[String] = json["OpeningHours"]["Monday"]["From"].string!.componentsSeparatedByString(":") 
    let monClose:[String] = json["OpeningHours"]["Monday"]["To"].string!.componentsSeparatedByString(":") 
    let tueOpen:[String] = json["OpeningHours"]["Tuesday"]["From"].string!.componentsSeparatedByString(":") 
    let tueClose:[String] = json["OpeningHours"]["Tuesday"]["To"].string!.componentsSeparatedByString(":") 
    let wedOpen:[String] = json["OpeningHours"]["Wednesday"]["From"].string!.componentsSeparatedByString(":") 
    let wedClose:[String] = json["OpeningHours"]["Wednesday"]["To"].string!.componentsSeparatedByString(":") 
    let thuOpen:[String] = json["OpeningHours"]["Thursday"]["From"].string!.componentsSeparatedByString(":") 
    let thuClose:[String] = json["OpeningHours"]["Thursday"]["To"].string!.componentsSeparatedByString(":") 
    let friOpen:[String] = json["OpeningHours"]["Friday"]["From"].string!.componentsSeparatedByString(":") 
    let friClose:[String] = json["OpeningHours"]["Friday"]["To"].string!.componentsSeparatedByString(":") 
    let satOpen:[String] = json["OpeningHours"]["Saturday"]["From"].string!.componentsSeparatedByString(":") 
    let satClose:[String] = json["OpeningHours"]["Saturday"]["To"].string!.componentsSeparatedByString(":") 
    let sunOpen:[String] = json["OpeningHours"]["Sunday"]["From"].string!.componentsSeparatedByString(":") 
    let sunClose:[String] = json["OpeningHours"]["Sunday"]["To"].string!.componentsSeparatedByString(":") 

Cách mẹ đẻ:

var monOpen:[String] = [] 
    var monClose:[String] = [] 
    var tueOpen:[String] = [] 
    var tueClose:[String] = [] 
    var wedOpen:[String] = [] 
    var wedClose:[String] = [] 
    var thuOpen:[String] = [] 
    var thuClose:[String] = [] 
    var friOpen:[String] = [] 
    var friClose:[String] = [] 
    var satOpen:[String] = [] 
    var satClose:[String] = [] 
    var sunOpen:[String] = [] 
    var sunClose:[String] = [] 
    var openDescription:String = "" 

    if let attractionsArray = orgJson as? NSArray{ 
     if let attraction = attractionsArray[0] as? NSDictionary{ 
      if let openHours = attraction["OpeningHours"] as? NSDictionary{ 
       if let day = openHours["Monday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         monOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         monClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Tuesday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         tueOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         tueClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Wednesday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         wedOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         wedClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Thursday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         thuOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         thuClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Friday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         friOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         friClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Saturday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         satOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         satClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let day = openHours["Sunday"] as? NSDictionary{ 
        if let open = day["From"] as? String{ 
         sunOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"] as? String{ 
         sunClose = close.componentsSeparatedByString(":") 
        } 
       } 
       if let desc = openHours["OpeningHoursGenericExceptions"] as? String{ 
        openDescription = desc 
       } 
      } 
     } 
    } 

Đây chỉ là một phần của dữ liệu được phân tích cú pháp để hiệu suất thực sự đáng chú ý trong ứng dụng.

Tôi đoán câu hỏi là, đã i sử dụng không đúng cách hoặc SwiftyJSON được này để được mong đợi?

Trả lời

20

Trước hết, "cách tự nhiên" của bạn không phải là tương đương với "Swifty cách".

Phiên bản SwiftyJSON có 45 subscript quyền truy cập, nhưng cách gốc chỉ có 23 subscript quyền truy cập.

Để thực hiện "cách bản địa" tương đương, nó phải là một cái gì đó như:

let openDescription = attraction["OpeningHours"]!["OpeningHoursGenericExceptions"] as String 
let monOpen = (attraction["OpeningHours"]!["Monday"]!!["From"] as String).componentsSeparatedByString(":") 
let monClose = (attraction["OpeningHours"]!["Monday"]!!["To"] as String).componentsSeparatedByString(":") 
let tueOpen = (attraction["OpeningHours"]!["Tuesday"]!!["From"] as String).componentsSeparatedByString(":") 
let tueClose = (attraction["OpeningHours"]!["Tuesday"]!!["To"]! as String).componentsSeparatedByString(":") 
// ... 

hoặc "Swifty cách" nên được như:

let openHours = json[0]["OpeningHours"] 
var day:JSON 

day = openHours["Monday"] 
if let open = day["From"].string { 
    monOpen = open.componentsSeparatedByString(":") 
} 
if let close = day["To"].string { 
    monClose = close.componentsSeparatedByString(":") 
} 
day = openHours["Tuesday"] 
if let open = day["From"].string { 
    tueOpen = open.componentsSeparatedByString(":") 
} 
if let close = day["To"].string { 
    tueClose = close.componentsSeparatedByString(":") 
} 
// ... 

Dù sao, Có, SwiftyJSON là chậm. Hãy đo:

import Foundation 
import XCTest 

let orgJson:AnyObject = [ 
    [ 
     "OpeningHours": [ 
      "OpeningHoursGenericExceptions": "test", 
      "Monday": ["From":"1:2:3","To":"1:2:3"], 
      "Tuesday": ["From":"1:2:3","To":"1:2:3"], 
      "Wednesday": ["From":"1:2:3","To":"1:2:3"], 
      "Thursday": ["From":"1:2:3","To":"1:2:3"], 
      "Friday": ["From":"1:2:3","To":"1:2:3"], 
      "Saturday": ["From":"1:2:3","To":"1:2:3"], 
      "Sunday": ["From":"1:2:3","To":"1:2:3"], 
     ] 
    ] 
] 
let json = JSON(orgJson) 

class JSONTestTests: XCTestCase { 

    func testNativeSubscript() { 
     measureBlock {() -> Void in 

      for _ in 0 ..< 400 { 
       autoreleasepool { 
        if let attraction = orgJson[0] as? NSDictionary { 
         let openDescription = attraction["OpeningHours"]!["OpeningHoursGenericExceptions"] as String 
         let monOpen = (attraction["OpeningHours"]!["Monday"]!!["From"] as String).componentsSeparatedByString(":") 
         let monClose = (attraction["OpeningHours"]!["Monday"]!!["To"] as String).componentsSeparatedByString(":") 
         let tueOpen = (attraction["OpeningHours"]!["Tuesday"]!!["From"] as String).componentsSeparatedByString(":") 
         let tueClose = (attraction["OpeningHours"]!["Tuesday"]!!["To"] as String).componentsSeparatedByString(":") 
         let wedOpen = (attraction["OpeningHours"]!["Wednesday"]!!["From"] as String).componentsSeparatedByString(":") 
         let wedClose = (attraction["OpeningHours"]!["Wednesday"]!!["To"] as String).componentsSeparatedByString(":") 
         let thuOpen = (attraction["OpeningHours"]!["Thursday"]!!["From"] as String).componentsSeparatedByString(":") 
         let thuClose = (attraction["OpeningHours"]!["Thursday"]!!["To"] as String).componentsSeparatedByString(":") 
         let friOpen = (attraction["OpeningHours"]!["Friday"]!!["From"] as String).componentsSeparatedByString(":") 
         let friClose = (attraction["OpeningHours"]!["Friday"]!!["To"] as String).componentsSeparatedByString(":") 
         let satOpen = (attraction["OpeningHours"]!["Saturday"]!!["From"] as String).componentsSeparatedByString(":") 
         let satClose = (attraction["OpeningHours"]!["Saturday"]!!["To"] as String).componentsSeparatedByString(":") 
         let sunOpen = (attraction["OpeningHours"]!["Sunday"]!!["From"] as String).componentsSeparatedByString(":") 
         let sunClose = (attraction["OpeningHours"]!["Sunday"]!!["To"] as String).componentsSeparatedByString(":") 
         XCTAssertEqual(monOpen, ["1","2","3"], "") 
         XCTAssertEqual(openDescription, "test") 
        } 
       } 
      } 
     } 
    } 

    func testJSONSubscript() { 
     measureBlock {() -> Void in 
      for _ in 0 ..< 400 { 
       autoreleasepool { 
        let attraction = json[0] 
        let openDescription:String = attraction["OpeningHours"]["OpeningHoursGenericExceptions"].string! 
        let monOpen:[String] = attraction["OpeningHours"]["Monday"]["From"].string!.componentsSeparatedByString(":") 
        let monClose:[String] = attraction["OpeningHours"]["Monday"]["To"].string!.componentsSeparatedByString(":") 
        let tueOpen:[String] = attraction["OpeningHours"]["Tuesday"]["From"].string!.componentsSeparatedByString(":") 
        let tueClose:[String] = attraction["OpeningHours"]["Tuesday"]["To"].string!.componentsSeparatedByString(":") 
        let wedOpen:[String] = attraction["OpeningHours"]["Wednesday"]["From"].string!.componentsSeparatedByString(":") 
        let wedClose:[String] = attraction["OpeningHours"]["Wednesday"]["To"].string!.componentsSeparatedByString(":") 
        let thuOpen:[String] = attraction["OpeningHours"]["Thursday"]["From"].string!.componentsSeparatedByString(":") 
        let thuClose:[String] = attraction["OpeningHours"]["Thursday"]["To"].string!.componentsSeparatedByString(":") 
        let friOpen:[String] = attraction["OpeningHours"]["Friday"]["From"].string!.componentsSeparatedByString(":") 
        let friClose:[String] = attraction["OpeningHours"]["Friday"]["To"].string!.componentsSeparatedByString(":") 
        let satOpen:[String] = attraction["OpeningHours"]["Saturday"]["From"].string!.componentsSeparatedByString(":") 
        let satClose:[String] = attraction["OpeningHours"]["Saturday"]["To"].string!.componentsSeparatedByString(":") 
        let sunOpen:[String] = attraction["OpeningHours"]["Sunday"]["From"].string!.componentsSeparatedByString(":") 
        let sunClose:[String] = attraction["OpeningHours"]["Sunday"]["To"].string!.componentsSeparatedByString(":") 
        XCTAssertEqual(monOpen, ["1","2","3"], "") 
       } 
      } 
     } 
    } 

    func testNativeBinding() { 
     measureBlock {() -> Void in 
      for _ in 0 ..< 400 { 
       autoreleasepool { 
        var monOpen:[String] = [] 
        var monClose:[String] = [] 
        var tueOpen:[String] = [] 
        var tueClose:[String] = [] 
        var wedOpen:[String] = [] 
        var wedClose:[String] = [] 
        var thuOpen:[String] = [] 
        var thuClose:[String] = [] 
        var friOpen:[String] = [] 
        var friClose:[String] = [] 
        var satOpen:[String] = [] 
        var satClose:[String] = [] 
        var sunOpen:[String] = [] 
        var sunClose:[String] = [] 
        var openDescription:String = "" 

        if let attractionsArray = orgJson as? NSArray{ 
         if let attraction = attractionsArray[0] as? NSDictionary{ 
          if let openHours = attraction["OpeningHours"] as? NSDictionary{ 
           if let day = openHours["Monday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             monOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             monClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Tuesday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             tueOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             tueClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Wednesday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             wedOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             wedClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Thursday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             thuOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             thuClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Friday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             friOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             friClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Saturday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             satOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             satClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let day = openHours["Sunday"] as? NSDictionary{ 
            if let open = day["From"] as? String{ 
             sunOpen = open.componentsSeparatedByString(":") 
            } 
            if let close = day["To"] as? String{ 
             sunClose = close.componentsSeparatedByString(":") 
            } 
           } 
           if let desc = openHours["OpeningHoursGenericExceptions"] as? String{ 
            openDescription = desc 
           } 
          } 
         } 
        } 
        XCTAssertEqual(monOpen, ["1","2","3"], "") 
       } 
      } 
     } 
    } 
    func testJSONBinding() { 
     measureBlock {() -> Void in 
      for _ in 0 ..< 400 { 
       autoreleasepool { 
        var monOpen:[String] = [] 
        var monClose:[String] = [] 
        var tueOpen:[String] = [] 
        var tueClose:[String] = [] 
        var wedOpen:[String] = [] 
        var wedClose:[String] = [] 
        var thuOpen:[String] = [] 
        var thuClose:[String] = [] 
        var friOpen:[String] = [] 
        var friClose:[String] = [] 
        var satOpen:[String] = [] 
        var satClose:[String] = [] 
        var sunOpen:[String] = [] 
        var sunClose:[String] = [] 
        var openDescription:String = "" 

        let openHours = json[0]["OpeningHours"] 
        var day:JSON 

        day = openHours["Monday"] 
        if let open = day["From"].string { 
         monOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         monClose 
          = close.componentsSeparatedByString(":") 
        } 
        day = openHours["Tuesday"] 
        if let open = day["From"].string { 
         tueOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         tueClose = close.componentsSeparatedByString(":") 
        } 
        day = openHours["WednesDay"] 
        if let open = day["From"].string { 
         wedOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         wedClose = close.componentsSeparatedByString(":") 
        } 
        day = openHours["Thursday"] 
        if let open = day["From"].string { 
         thuOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         thuClose = close.componentsSeparatedByString(":") 
        } 
        day = openHours["Friday"] 
        if let open = day["From"].string { 
         friOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         friClose = close.componentsSeparatedByString(":") 
        } 
        day = openHours["Saturday"] 
        if let open = day["From"].string { 
         satOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         satClose = close.componentsSeparatedByString(":") 
        } 
        day = openHours["Sunday"] 
        if let open = day["From"].string { 
         sunOpen = open.componentsSeparatedByString(":") 
        } 
        if let close = day["To"].string { 
         sunClose = close.componentsSeparatedByString(":") 
        } 
        XCTAssertEqual(monOpen, ["1","2","3"], "") 
       } 
      } 
     } 
    } 

} 

Đầu ra:

<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testJSONBinding]' measured [Time, seconds] average: 0.804, relative standard deviation: 5.592%, values: [0.835687, 0.814827, 0.819685, 0.841900, 0.764961, 0.845202, 0.691442, 0.779255, 0.818213, 0.830698], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100 
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testJSONSubscript]' measured [Time, seconds] average: 4.247, relative standard deviation: 3.496%, values: [4.019640, 4.004123, 4.146146, 4.194535, 4.487171, 4.300971, 4.310613, 4.408405, 4.318354, 4.279362], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100 
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testNativeBinding]' measured [Time, seconds] average: 0.223, relative standard deviation: 2.773%, values: [0.221099, 0.227395, 0.218860, 0.225989, 0.227128, 0.222370, 0.229956, 0.214535, 0.210818, 0.229868], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100 
<unknown>:0: Test Case '-[JSONTestTests.JSONTestTests testNativeSubscript]' measured [Time, seconds] average: 0.362, relative standard deviation: 17.528%, values: [0.346285, 0.316185, 0.333650, 0.339416, 0.330243, 0.354034, 0.378730, 0.269519, 0.486904, 0.467607], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100 
  • SwiftyJSON của bạn: 4,247
  • bạn Quê quán: 0,223
  • SwiftyJSON My: 0,804
  • My Quê quán: 0,362

Bằng cách này, nếu tôi là bạn, tôi sẽ làm một cái gì đó như:

if let hours = orgJson[0]?["OpeningHours"] as? NSDictionary { 
    let openDescription = hours["OpeningHoursGenericExceptions"] as? String ?? "" 
    let monOpen = hours["Monday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let monClose = hours["Monday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let tueOpen = hours["Tuesday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let tueClose = hours["Tuesday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let wedOpen = hours["Wednesday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let wedClose = hours["Wednesday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let thuOpen = hours["Thursday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let thuClose = hours["Thursday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let friOpen = hours["Friday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let friClose = hours["Friday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let satOpen = hours["Saturday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let satClose = hours["Saturday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let sunOpen = hours["Sunday"]?["From"]??.componentsSeparatedByString?(":") as? [String] ?? [] 
    let sunClose = hours["Sunday"]?["To"]??.componentsSeparatedByString?(":") as? [String] ?? [] 

    // ... 
} 

Đó là lý nhanh chóng, an toàn, không quá phức tạp.


Tại sao SwiftyJSON chậm?

On subscript truy cập, SwiftyJSON làm:

  1. kiểm tra chính là String
  2. subscript lại với self[key:sub]
  3. kiểm tra các đối tượng cơ bản là NSDictionary
  4. subscript tiềm ẩn NSDictionary với phím
  5. cung cấp
  6. xây dựng JSON đối tượng với kết quả
  7. return

lẽ trình biên dịch tối ưu hóa một số bước, nhưng "chậm hơn so với bản địa" có phần không thể tránh khỏi :)

+0

Cảm ơn bạn đã có câu trả lời rất kỹ lưỡng! Và với điểm chuẩn! Kể từ khi tôi rất mới tại Swift (tôi đoán rất nhiều người là :) rất nhiều mã hóa là đầu tiên-thử-thử-và-lỗi và tôi đã làm phân tích cú pháp JSON như đề nghị trong tập tin SwiftyJSON README. Nhìn vào các ví dụ khác nhau của các phương pháp phân tích cú pháp mà tôi không hối tiếc khi rút ra khỏi dự án của mình, sự phức tạp của phân tích cú pháp "gốc" không thực sự là vấn đề và thêm hiệu suất khác biệt mà tôi không thấy là một tùy chọn. – Simpa

+0

Tôi có nghĩa là không có hành vi phạm tội với người sáng tạo của Swifty, tôi nghĩ rằng nó có thể có sử dụng tuyệt vời cho rất nhiều nhà phát triển. Nhưng googling 'nhanh chóng phân tích cú pháp json' gần như chỉ cho kết quả bằng cách sử dụng swifty đã cho tôi ấn tượng đó là con đường để đi. Nhưng có lẽ nó không dành cho tất cả mọi người? :) – Simpa

+0

@Simpa trong thế giới Swift, rất nhiều lần truy cập trong Google không thể tin cậy được. Người ta sẽ có ấn tượng rằng Objective-C đã chết, Cocoapods được chấp nhận như là một tiêu chuẩn, vv ... ... trên thực tế, tôi nghĩ rằng rất nhiều những sự xuất hiện này là vấn đề. Tuy nhiên, SwiftyJSON có quá chậm để sử dụng không? Đó là một câu hỏi khác, nhưng nếu bạn đã nhận được những kết quả này ban đầu, bạn có thể không nhận thấy. –