【问题标题】:How do I use json instead of plist to populate TableView如何使用 json 而不是 plist 来填充 TableView
【发布时间】:2016-08-18 11:12:57
【问题描述】:

我有一个工作应用程序,它从远程服务器上的 pList 获取数据。但是,我现在想使用 json 而不是 plist 并且正在努力理解如何做到这一点!任何帮助都非常感谢,任何例子都很棒。

一些选定的代码 - 首先下载 plist,然后使用下载的 plist 填充 TableView。注意:我没有包含所有代码。

@IBAction func startDownload(sender: AnyObject) {
progressView.hidden = false

    let url = NSURL(string: "http://ftp.iphoneData@dittodata.host-ed.me/Annotations/myAnnotationsKalkan.plist")!
    downloadTask = backgroundSession.downloadTaskWithURL(url)
    downloadTask.resume()
}

func showFileWithPath(path: String){
    let isFileFound:Bool? = NSFileManager.defaultManager().fileExistsAtPath(path)
    if isFileFound == true{
        let viewer = UIDocumentInteractionController(URL: NSURL(fileURLWithPath: path))
        viewer.delegate = self
        viewer.presentPreviewAnimated(true)
       // print("file is found")
    }
}

@IBOutlet var progressView: UIProgressView!
 override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// 1
func URLSession(session: NSURLSession,
    downloadTask: NSURLSessionDownloadTask,
    didFinishDownloadingToURL location: NSURL){

    let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
    let documentDirectoryPath:String = path[0]
    let fileManager = NSFileManager()
    let destinationURLForFile = NSURL(fileURLWithPath: documentDirectoryPath.stringByAppendingString("/myAnnotationsKalkan.plist.plist"))

    if fileManager.fileExistsAtPath(destinationURLForFile.path!){
        showFileWithPath(destinationURLForFile.path!)
    }
    else{
        do {
            try fileManager.moveItemAtURL(location, toURL: destinationURLForFile)
//             show file
            showFileWithPath(destinationURLForFile.path!)
        }catch{
            print("An error occurred while moving file to destination url")
        }
    }
}

// 2
func URLSession(session: NSURLSession,
                downloadTask: NSURLSessionDownloadTask,
                didWriteData bytesWritten: Int64,
                             totalBytesWritten: Int64,
                             totalBytesExpectedToWrite: Int64){
    progressView.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
}

func URLSession(session: NSURLSession,
                task: NSURLSessionTask,
                didCompleteWithError error: NSError?){
    downloadTask = nil
    progressView.setProgress(0.0, animated: true)

    if (error != nil) {
        print(error?.description)
    }else{
      //  print("The task finished transferring data successfully")
         progressView.hidden = true
    }
}


//  TableViewController.swift
    /  museumTemplate

//

import UIKit


class MyTableViewController: UITableViewController {

var titleData = [String]()
var subTitleData = [String]()
var stateData = [String]()
var codeData = [String]()
var infoData = [String]()
var openData = [String]()
var phoneData = [String]()
var emailData = [String]()
var webData = [String]()
var latData = [Double]()
var lonData = [Double]()

var titleToPass = [String]()
var thisState = [String]()
var stateOrAlpha = ""
var titleText = ""


override func viewDidLoad() {
    super.viewDidLoad()

navigationItem.title = titleText

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    let sourcePath = documentsPath.stringByAppendingPathComponent("myAnnotationsKalkan.plist.plist")

    if let content = NSArray(contentsOfFile: sourcePath as String){


    let descriptor = NSSortDescriptor(key: stateOrAlpha, ascending: true)
    let myMuseum = content.sortedArrayUsingDescriptors([descriptor])

        for item in myMuseum{
                titleData.append(item.objectForKey("title") as! String)
                subTitleData.append(item.objectForKey("subtitle") as! String)
                infoData.append(item.objectForKey("info") as! String)
                phoneData.append(item.objectForKey("phone") as! String)
                webData.append(item.objectForKey("web") as! String)
                emailData.append(item.objectForKey("email") as! String)
                latData.append(item.objectForKey("latitude") as! Double)
                lonData.append(item.objectForKey("longitude") as! Double)
            }
        }
    }

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // Return the number of rows in the section.
    return titleData.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
 let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as UITableViewCell

    // Configure the cell..title and subTitle.
   cell.textLabel!.text = titleData[indexPath.row]
    return cell
    }

【问题讨论】:

  • 使用 13(!) 个数组作为数据源是非常糟糕的编程习惯。 Swift 是一种面向对象的语言,因此请使用自定义类或结构。与属性列表不同,JSON 文件是纯文本。您可以使用dataTask 而不是downloadTask,并且必须将文本转换(反序列化)为数组或字典。
  • 感谢您的建议和信息
  • 我应该补充一点,我确实在其他应用程序的类似代码中使用了自定义类。这个我正在试验,又快又脏 :-)

标签: json uitableview swift2 plist


【解决方案1】:

我使用 Alamofire,它更容易和更安全地执行 Web 请求,但这里有一个没有它的代码:

 let urlPath = "YourUrlRequest"
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: urlPath)!
            session.dataTaskWithURL(url) {( data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in

                if let  responseData = data {
                do {
                    let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData, options: []) as! NSArray
                    for dataDict : AnyObject in jsonObject {

                        let idj: String = dataDict.objectForKey("id") as!String
                        let namej: String = dataDict.objectForKey("name") as! String
                        let indicativej: String = dataDict.objectForKey("indicative") as! String
                        let flagj: String = dataDict.objectForKey("flag") as! String
                        saveCountryFromWeb(idj, name: namej, indicative: indicativej, flag: flagj)

                    }
                } catch let error as NSError {
                    print("Failed to load: \(error.localizedDescription)")
                }
                }

            }.resume()

希望对您有所帮助,如果您想要我推荐的 alamofire 样品,请告诉我 ;)

【讨论】:

  • Kika_Fortez 没有使用过 Alamofire,所以请回复:样品。虽然我的意图是在整理时使用 Firebase 进行数据访问。感谢您的积极帮助
  • 好的,所以用firebase检索数据你不需要使用它们,因为firebase默认有他的方法,所以我会放一个firebase的例子。请勾选正确答案。
  • 终于有时间玩你的代码了。这行出现错误 let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData, options: []) as! NSArray SIGABRT - 无法将“__NSCFDictionary”(0x44c5c0)类型的值转换为“NSArray”(0x44c2f0)。
  • 好的!尝试改为此代码: let jsonObject = try NSJSONSerialization.JSONObjectWithData(responseData, options: []) as! NSDictionary
  • 谢谢。但是,我已经尝试过了,并提出了错误“键:AnyObject,值:AnyObject)”不符合协议“AnyObject”,但是,我得到了一些工作代码(欢迎任何 cmets/改进)。接下来,如果时间允许,我将尝试实现您为 Firebase 提供的示例 :-) 祝您好运
【解决方案2】:
func retrieveBarcodeData(){

    let databaseref = FIRDatabase.database().reference()
    databaseref.child("barcodes").queryOrderedByKey().observeEventType(.ChildAdded, withBlock: {
        snapshot in


        let codig = snapshot.value!["codigo"] as! String
        let desc = snapshot.value!["designacao"] as! String
        let Url = snapshot.value!["ImageURL"] as! String

        barcodes.insert(BarCodeStruct(code: codig, description: desc, ImageURL: Url),atIndex: 0)
        self.tableView.reloadData()



    })

}

别忘了在 firebase 中配置你的数据库,并使用 cocoapods 安装 firebase 并将 FIRApp.configure() 放入你的 appDelegate didFinishLaunchingWithOptions

【讨论】:

    【解决方案3】:

    我尝试使用此代码从服务器下载一个简单的 json 文件,它似乎可以工作:

        override func viewDidLoad() {
        super.viewDidLoad()
    
        let requestURL: NSURL = NSURL(string: "http://ftp.iphoneData@dittodata.host-ed.me/Annotations/testData4.json")!
        let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithRequest(urlRequest) {
            (data, response, error) -> Void in
        let httpResponse = response as! NSHTTPURLResponse
        let statusCode = httpResponse.statusCode
    
            if (statusCode == 200) {
                print("File downloaded.")
       //         print(testData4.json)
                do{
    
                    let json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
    
                    if let users = json["users"] as? [[String: AnyObject]] {
                        for user in users {
                            if let name = user["name"] as? String {
                            if let subtitle = user["subtitle"] as? String {
                            print(name,subtitle)
                                }
                            }
                        }
                    }    
                }catch {
                    print("Error with Json: \(error)")
                }
            }
        }
        task.resume()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多