2015-04-03 92 views
1

我正在使用nsxmlparser来解析xml。 但didstartelement往往没有被称为。didstartelement ofiten没有被迅速调用

我调查了这个问题,但我找不到答案。

这是我的代码。

  // 
     // WorkList.swift 
     // ShotAlertForSwift 
     // 
     // Created by xxxxxx on 3/16/15. 
     // Copyright (c) 2015 xxxxxxxx. All rights reserved. 
     // 

     import UIKit 


     class WorkList: UIViewController,UITableViewDataSource,UITableViewDelegate,NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSXMLParserDelegate{ 

      @IBOutlet weak var workview: UITableView! 

      var appCode:AppCode! 
      var workAry:NSMutableArray! 
      var param:NSMutableDictionary? 
      var start:Int = 0 
      var total:Int = 0 

      var isLoading = false 
      var initLoading = true 
      var nowLoading = false 
      var notParseFlag = false 
      var nowCount:Int = 0 
      var currentNodeName:String? 
      var currentNodeContent:String? 
      var footerIndicator: UIActivityIndicatorView! 
      var session:NSURLSession! 
      var workdata:NSMutableArray! 

      let listmax:Int = 100 
      let PageSize = 20 


      var xmlUrl : NSURL! 
       { 
       didSet{ 

        println(self.xmlUrl) 
        if (!self.isLoading) { 
         if self.initLoading == true{ 
          SVProgressHUD.showWithStatus("読み込み中") 
         }else{ 
          self.footerIndicator.startAnimating() 
         } 
         self.nowCount = workdata.count 
         self.isLoading = true 

         let request : NSURLRequest = NSURLRequest(URL:xmlUrl) 

         //タイムアウトは15秒 
         var config = NSURLSessionConfiguration.defaultSessionConfiguration() 
         config.timeoutIntervalForRequest = 10 

         self.session = NSURLSession(configuration: config, 
          delegate: self, 
          delegateQueue: NSOperationQueue.mainQueue()) 





         var task:NSURLSessionDataTask = self.session.dataTaskWithRequest(request) 
         task.resume() 

        } 

       } 
      } 
      var xmlUrlStr:String? 

      func showAlert(){ 
       //Cancel 一つだけしか指定できない 
       var alert:UIAlertController = UIAlertController(title:"通信エラー", 
        message: "通信に失敗しました。もう一度やり直してください", 
        preferredStyle: UIAlertControllerStyle.Alert) 

       let otherAction = UIAlertAction(title: "OK", style: .Default) { 
        action in NSLog("OKOK") 
       } 
       alert.addAction(otherAction) 
       presentViewController(alert, animated: true, completion: nil) 

      } 



      override func viewDidLoad() { 
       super.viewDidLoad() 
       workdata = NSMutableArray() 
       // Do any additional setup after loading the view, typically from a nib. 
       var nib = UINib(nibName: "WorkItemCell", bundle:nil) 
       self.workview.registerNib(nib, forCellReuseIdentifier:"WorkItemCell") 
       nib = UINib(nibName: "NoCountCell", bundle:nil) 
       self.workview.registerNib(nib, forCellReuseIdentifier:"NoCountCell") 
       footerIndicator = UIActivityIndicatorView() 

       appCode = AppCode.init() 

       _setParameter() 

       //_loadSegment(0, size: 20) 
       let paramStr = self.param?.urlEncodedString() 
     //println(Const().SHOT_DOMAIN) 
       self.xmlUrlStr = Const().SHOT_DOMAIN+Const().WORK_LIST+"?"+paramStr! 
       self.xmlUrl = NSURL(string:self.xmlUrlStr!) 

      } 

      override func viewWillDisappear(animated: Bool) { 
       SVProgressHUD.dismiss() 
       self.footerIndicator.stopAnimating() 
       self.notParseFlag = true 
       self.cancelConnect() 


      } 

      func _setParameter(){ 
       self.param = NSMutableDictionary() 
       if appCode.codeArea != nil && appCode.codeArea != ""{ 
        self.param?.setValue(appCode.codeArea, forKey: "a") 
       } 
       if appCode.codePref != nil && appCode.codePref != ""{ 
        self.param?.setValue(appCode.codePref, forKey: "prefcode") 
       } 
       if appCode.codeStartday != nil && appCode.codeStartday != ""{ 
        self.param?.setValue(appCode.codeStartday, forKey: "wdf") 
       } 
       if appCode.codeMinimumday != nil && appCode.codeMinimumday != ""{ 
        self.param?.setValue(appCode.codeMinimumday, forKey: "md") 
       } 
       if appCode.codeMainjob != nil && appCode.codeMainjob != ""{ 
        self.param?.setValue(appCode.codeMainjob, forKey: "mj") 
       } 
       if appCode.codeTag != nil && appCode.codeTag != ""{ 
        self.param?.setValue(appCode.codeTag, forKey: "tags") 
       } 
       self.param?.setValue(String(start+1), forKey: "start") 
       self.param?.setValue(String(PageSize), forKey: "results") 
       self.param?.setValue("xml", forKey: "output") 
       self.param?.setValue(String(1), forKey: "apliflag") 
       self.param?.setValue("key_001", forKey: "key_api") 

     //  println(appCode.codePref) 
     //  println(self.param) 
      } 


      /* 
      Cellが選択された際に呼び出される. 
      */ 
      func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

       let workdic: AnyObject = workdata[indexPath.row] 
       let workid = workdic.objectForKey("WorkId") as String 

       let detailUrl = Const().SHOT_DOMAIN+Const().WORK_DETAIL+"/"+workid 

       let web:Web! = self.storyboard?.instantiateViewControllerWithIdentifier("web") as Web 
       web.url = detailUrl 

       self.navigationController?.pushViewController(web, animated: true) 



      } 


      func numberOfSectionsInTableView(tableView: UITableView!) -> Int { 
       return 1 
      } 

      func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{ 
       if total == 0{ 
        return self.view.frame.size.height 
       } 

       return 185 
      } 



      func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

       if total == 0{ 
        return 1 
       } 
     //println("============================================") 
     //println(total) 
     //println(self.workdata.count) 
     //println("============================================") 
       return self.workdata.count 

      } 



      /* 
      Cellに値を設定する. 
      */ 
      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

       // Cellの.を取得する. 

       if total > 0{ 
        let wcell: WorkItemCell = tableView.dequeueReusableCellWithIdentifier("WorkItemCell", forIndexPath: indexPath) as WorkItemCell 

        let workdic: AnyObject = workdata[indexPath.row] 

        let minimumday = workdic.objectForKey("MinimumWorkDay") as String 

        let catchcopy = workdic.objectForKey("CatchCopy") as String 
        let payment = workdic.objectForKey("Payment") as String 
        let paymentunitname = workdic.objectForKey("PaymentUnitName") as String 
        var stationname = workdic.objectForKey("StationName") as? String 
        let applyenddate = workdic.objectForKey("ApplyEndDate") as String 
        let applyenddatediff = workdic.objectForKey("ApplyEndDateDiff") as String 
        var mainjobcodename = workdic.objectForKey("MainJobCodeName") as? String 
        let optiontags = workdic.objectForKey("OptionTags") as? String 
        let tags = workdic.objectForKey("Tags") as? String 
        let workstartdate = workdic.objectForKey("WorkStartDate") as String 


        wcell.minimumdayLabel.text = minimumday+"日" 
        wcell.catchcopyLabel.text = catchcopy 
        if stationname == nil{ 
         stationname = "" 
        } 
        wcell.stationLabel.text = "最寄り駅:"+stationname! 
        wcell.paymentunitnameLabel.text = paymentunitname 
        wcell.paymentLabel.text = payment+"円" 

        let diff = applyenddatediff.toInt() 
        wcell.limittitleLabel.text = "応募締切" 
        if diff < 1{ 
         wcell.limitLabel.textColor = UIColor.redColor() 
         let limitStr = "残り"+applyenddatediff+"時間" 
         wcell.limitLabel.text = limitStr 
        }else if diff >= 1 && diff < 24 { 
         wcell.limitLabel.textColor = UIColor.blackColor() 
         let limitStr = "残り"+applyenddatediff+"時間" 
         wcell.limitLabel.text = limitStr 
        }else{ 
         wcell.limitLabel.textColor = UIColor.blackColor() 

         let limitStr = applyenddate 
         wcell.limitLabel.text = limitStr 

        } 


        if mainjobcodename == nil{ 
         mainjobcodename = "" 
        } 

        //タグの処理 
        var tagAry:NSMutableArray? 
        if tags != nil { 
         tagAry?.addObject(tags!) 
        } 
        if optiontags != nil { 
         tagAry?.addObject(optiontags!) 
        } 
        var viewTag:String! = "" 
        if(tagAry?.count > 0){ 
         //println("---------------") 
         viewTag = tagAry!.componentsJoinedByString(",") 
        } 


        wcell.mainjobLabel.text = "職種:"+mainjobcodename! 
        wcell.optiontagLabel.text = "こだわり条件:"+viewTag 

        wcell.workstartdateLabel.text = "勤務開始日:"+workstartdate 

        return wcell 
       }else{ 

        let nocell: NoCountCell = tableView.dequeueReusableCellWithIdentifier("NoCountCell", forIndexPath: indexPath) as NoCountCell 
        nocell.conditionButton.addTarget(self, action: "onClickBack:", forControlEvents: .TouchUpInside) 

        //初期が終わったらfalse 
        if self.initLoading{ 
         nocell.conditionButton.hidden = true 
         nocell.messageLabel.hidden = true 
        }else{ 
         nocell.conditionButton.hidden = false 
         nocell.messageLabel.hidden = false 
        } 

        return nocell 
       } 

      } 

      func scrollViewDidScroll(scrollView: UIScrollView!) { 
       var offset = scrollView.contentOffset.y 
       var maxOffset = scrollView.contentSize.height - scrollView.frame.size.height 


       //nowLoadgingをtrueにするのは、2重にロードを防ぐため 
       //0件時には処理しない 
       //20であまりがある場合、もう無いので、処理しない(かつ、totalに達してない) 
       //100件以上もロードしない 
       //println(self.workdata.count) 
       if (maxOffset - offset) <= 40 
        && workdata.count > 0 
        && !self.nowLoading 
        && ((self.workdata.count)%20 == 0 && self.workdata.count < total && self.workdata.count < self.listmax){ 

        self.nowLoading = true 
        self.start = self.workdata.count 
        _setParameter() 

        let paramStr = self.param?.urlEncodedString() 

        self.xmlUrlStr = Const().SHOT_DOMAIN+Const().WORK_LIST+"?"+paramStr! 
        self.xmlUrl = NSURL(string:self.xmlUrlStr!) 
       } 

      } 



      func onClickBack(sender: UIButton){ 

       self.navigationController?.popViewControllerAnimated(true) 
      } 


      // NSXMLParserDelegate 

      var parseKey : String? = nil 
      var tmpEntry : NSMutableDictionary! = nil 

      let resultKey = "Result" 
      let resultSetKey = "ResultSet" 
      let urlKey = "url" 

      func parserDidStartDocument(parser: NSXMLParser!) 
      { 
       println("parse start") 
       println(parser) 

      } 


      func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!){ 

       parseKey = elementName 

       if elementName == resultKey { 
        tmpEntry = NSMutableDictionary() 

       } else if elementName == resultSetKey { 
        let attr = attributeDict as NSDictionary 

        let totalStr = attr.objectForKey("totalResultsAvailable") as String 
        let totalreturnstr = attr.objectForKey("totalResultsReturned") as String 

        total = totalStr.toInt()! 
       } 
      } 

      func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) 
      { 

       if elementName == resultKey { 

        self.workdata.addObject(tmpEntry) 


       }else if parseKey != nil{ 
        if (elementName == parseKey && tmpEntry != nil){ 
         tmpEntry.setValue(currentNodeContent, forKey: parseKey!) 
        } 
       } 
       parseKey = nil 
       currentNodeContent = nil 
      } 

      func parser(parser: NSXMLParser!, foundCharacters string: String!) 
      { 
       currentNodeContent = string 
      } 

      func parserDidEndDocument(parser: NSXMLParser!) 
      { 
       if self.initLoading{ 
        SVProgressHUD.dismiss() 
       }else{ 
        self.footerIndicator.stopAnimating() 
       } 
       self.isLoading = false 
       self.initLoading = false 
       self.nowLoading = false 

       var footer = UIView() 
       //footer.backgroundColor = UIColor.clearColor() 
       // インジケータを作成する. 
       footerIndicator.color = UIColor.blackColor() 

       //self.footerIndicator.hidesWhenStopped = true 
       footerIndicator.frame.origin.x = self.view.frame.size.width/2 
       footer.addSubview(footerIndicator) 

       //ナビゲーションのタイトルに件数をセット 
       self.navigationItem.title = "検索結果:"+String(total)+"件" 

       //20で割ってもない場合は表示しない 
       if self.workdata.count%20 == 0 && self.workdata.count < total && self.workdata.count < self.listmax{ 
        self.workview.tableFooterView = footer 
       } 
       self.workview.reloadData() 
      } 




      override func didReceiveMemoryWarning() { 
       super.didReceiveMemoryWarning() 
       // Dispose of any resources that can be recreated. 
       println("didReceiveMemoryWarning") 
      } 


     } 


     extension WorkList { 
      func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void){ 
       println("request_start") 

       if response.isKindOfClass(NSHTTPURLResponse){ 
        let httpURLResponse:NSHTTPURLResponse = response as NSHTTPURLResponse 

        let statuscode = httpURLResponse.statusCode 
        println(statuscode) 

        if statuscode == 200{ 
         println("success") 

         let disposition:NSURLSessionResponseDisposition = NSURLSessionResponseDisposition.Allow 
         completionHandler(disposition) 
        }else{ 
         handleError() 
        } 
       } 


      } 
      func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask){ 
       println("didBecomeDownloadTask") 
      } 

      func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData){ 
       if !notParseFlag{ 
        println(NSString(data: data, encoding: NSUTF8StringEncoding)) 
        var parser : NSXMLParser? = NSXMLParser(data: data) 

        if parser != nil { 
         println("parser ok") 
         // NSXMLParserDelegateをセット 
         parser!.delegate = self; 
         parser!.parse() 

        } else { 
         // パースに失敗した時 
         println("failed to parse XML") 
        } 
       } 
      } 

      func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?){ 
       println(error) 
       if error != nil{ 
        //println("didCompleteWithError") 
        handleError() 
       } 


      } 
      func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?){ 
       println(error) 

       if error != nil{ 
        //println("didBecomeInvalidWithError") 
        handleError() 
       } 
      } 

      func cancelConnect(){ 
       self.session.getTasksWithCompletionHandler 
       { 
        (dataTasks, uploadTasks, downloadTasks) -> Void in 

        self.cancelTasksByUrl(dataTasks  as [NSURLSessionTask]) 

       } 
      } 

      func handleError(){ 
       if self.initLoading{ 
        SVProgressHUD.dismiss() 
       }else{ 
        self.footerIndicator.stopAnimating() 
       } 
       self.isLoading = false 
       self.initLoading = false 
       self.nowLoading = false 

       //アラートを表示して終了 
       showAlert() 

       self.workview.reloadData() 
      } 

      private func cancelTasksByUrl(tasks: [NSURLSessionTask]) 
      { 
       for task in tasks 
       { 
        task.cancel() 
       } 
      } 
     } 

     extension NSDictionary{ 
      func urlEncodedString() -> String { 

       var parts:NSMutableArray = NSMutableArray() 
       for key in self.allKeys { 

        let sKey = key as String 
        let value:String = self.objectForKey(key) as String 
        let eValue = value.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)! 
        var part:String! = (sKey+"="+eValue) as String! 
        parts.addObject(part) 
       } 
       return parts.componentsJoinedByString("&") 
      } 
     } 

我不明白为什么didstartelement有时没有被调用。 这是什么问题?

回答

0

我必须解决。 我将nsdata对象添加到nsmutabledata。 这是代码。

var data : NSMutableData? = nil 
public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData){ 



    self.data!.appendData(data) 
    ....you can write your code. 



}