You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift3中如何排序JSON数据并加载至UITableView?加载失败求助

Hey there! Let's work through your problem step by step—loading JSON into a UITableView and sorting that data in Swift 3 can trip you up if you're missing a few key pieces, so let's break it down clearly.

Step 1: Create Data Models for Your JSON Structure

Your JSON has nested objects (like address and company), so we'll make model classes to store this parsed data properly. Swift 3 doesn't have Codable (that came in Swift 4+), so we'll use dictionary-to-model initialization:

// Nested Address model
class Address: NSObject {
    var street: String?
    var suite: String?
    var city: String?
    var zipcode: String?
    
    init(dictionary: [String: Any]) {
        self.street = dictionary["street"] as? String
        self.suite = dictionary["suite"] as? String
        self.city = dictionary["city"] as? String
        self.zipcode = dictionary["zipcode"] as? String
        // Add lat/lng properties here if you need the geo data
    }
}

// Nested Company model
class Company: NSObject {
    var name: String?
    var catchPhrase: String?
    
    init(dictionary: [String: Any]) {
        self.name = dictionary["name"] as? String
        self.catchPhrase = dictionary["catchPhrase"] as? String
    }
}

// Main User model
class User: NSObject {
    var id: Int?
    var name: String?
    var username: String?
    var email: String?
    var address: Address?
    var phone: String?
    var website: String?
    var company: Company?
    
    init(dictionary: [String: Any]) {
        self.id = dictionary["id"] as? Int
        self.name = dictionary["name"] as? String
        self.username = dictionary["username"] as? String
        self.email = dictionary["email"] as? String
        
        // Parse nested address object
        if let addressDict = dictionary["address"] as? [String: Any] {
            self.address = Address(dictionary: addressDict)
        }
        
        // Parse nested company object
        if let companyDict = dictionary["company"] as? [String: Any] {
            self.company = Company(dictionary: companyDict)
        }
        
        self.phone = dictionary["phone"] as? String
        self.website = dictionary["website"] as? String
    }
}

Step 2: Parse JSON into a User Array

Next, we'll take your JSON data (whether from a local file or API) and convert it into an array of User objects.

For Local JSON Files:

var usersArray: [User] = []
@IBOutlet weak var tableView: UITableView!

func loadLocalJSON() {
    // Locate the JSON file in your app bundle
    guard let jsonPath = Bundle.main.path(forResource: "users", ofType: "json") else {
        print("Error: JSON file not found in bundle")
        return
    }
    
    do {
        let jsonData = try Data(contentsOf: URL(fileURLWithPath: jsonPath))
        // Convert data to JSON array
        guard let jsonArray = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [[String: Any]] else {
            print("Error: JSON is not a valid array")
            return
        }
        
        // Map JSON array to User objects
        usersArray = jsonArray.map { User(dictionary: $0) }
        // Refresh the table view
        tableView.reloadData()
    } catch let error {
        print("Parsing error: \(error.localizedDescription)")
    }
}

For API-Fetched JSON:

func fetchUsersFromAPI() {
    guard let apiURL = URL(string: "https://your-api-endpoint-here.com/users") else {
        print("Error: Invalid API URL")
        return
    }
    
    URLSession.shared.dataTask(with: apiURL) { [weak self] data, response, error in
        guard let data = data, error == nil else {
            print("Fetch error: \(error?.localizedDescription ?? "Unknown error")")
            return
        }
        
        do {
            guard let jsonArray = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: Any]] else {
                print("Error: API response is not a valid array")
                return
            }
            
            // Map to User array and refresh table on main thread
            self?.usersArray = jsonArray.map { User(dictionary: $0) }
            DispatchQueue.main.async {
                self?.tableView.reloadData()
            }
        } catch let error {
            print("Parsing error: \(error.localizedDescription)")
        }
    }.resume()
}

Step 3: Connect to UITableView Data Source

Make sure your view controller conforms to UITableViewDataSource and implement the required methods. Don't forget to set the table view's data source (via Storyboard outlets or code):

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.dataSource = self
    // Call your JSON loading function here
    loadLocalJSON()
    // OR fetchUsersFromAPI()
}

// MARK: - UITableView Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return usersArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Use your cell reuse identifier (set this in Storyboard first!)
    let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath)
    let currentUser = usersArray[indexPath.row]
    
    // Populate cell with user data
    cell.textLabel?.text = currentUser.name
    cell.detailTextLabel?.text = currentUser.email
    
    // Example: Show nested address data (city)
    if let userCity = currentUser.address?.city {
        cell.detailTextLabel?.text = "\(currentUser.email ?? "") | \(userCity)"
    }
    
    return cell
}

Step 4: Sort the User Array

To sort your data, add a sort call right after parsing the JSON. Here are common sorting options:

Sort by Name (Ascending):

usersArray.sort {
    guard let name1 = $0.name, let name2 = $1.name else { return false }
    return name1 < name2
}

Sort by ID (Descending):

usersArray.sort {
    guard let id1 = $0.id, let id2 = $1.id else { return false }
    return id1 > id2
}

Add this sort code right before reloading the table view. For example, in loadLocalJSON():

// After mapping to User array
usersArray = jsonArray.map { User(dictionary: $0) }
// Sort here
usersArray.sort {
    guard let name1 = $0.name, let name2 = $1.name else { return false }
    return name1 < name2
}
tableView.reloadData()

Quick Troubleshooting Tips

  • Double-check your JSON format: The sample JSON you provided is missing a closing } at the end—make sure your actual JSON is valid.
  • Ensure your table view's data source is connected (either via Storyboard or tableView.dataSource = self).
  • Always refresh the table view on the main thread (critical for API-fetched data).
  • Verify your cell reuse identifier matches what's in your code and Storyboard.

内容的提问来源于stack exchange,提问作者Ankit Kumawat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:33:38