2015-05-18 2 views
0

Привет Я использую следующую функцию для замены текущего контроллера корневого представления на новый контроллер корневого представления после сохранения пользователя «имя пользователя» во внутренней базе данных. Хотя код работает, и я могу сделать переключатель, но для перехода требуется очень много времени. когда-то целых 15 секунд.Приложение iOS: замена rootviewcontroller после выполнения входа в систему с помощью swift имеет значительную задержку

func switchRootViewController(rootViewController: UIViewController, animated: Bool, completion: (() -> Void)?) { 
    if animated { 
     UIView.transitionWithView(self.window!, duration: 0.5, options: .TransitionCrossDissolve, animations: { 
      let oldState: Bool = UIView.areAnimationsEnabled() 
      UIView.setAnimationsEnabled(false) 
      self.window!.rootViewController = rootViewController 
      UIView.setAnimationsEnabled(oldState) 
      }, completion: { (finished: Bool) ->() in 
       if (completion != nil) { 
        completion!() 
       } 
     }) 
    } else { 
     self.window!.rootViewController = rootViewController 
    } 
} 

Это, как я звоню функции:

api.postMulti(apiKey, contentType: "application/json", payLoad: payLoad, urlString: urlString, parameter: parameter){ (succeeded: Int, msg: String) ->() in 

     var alert = UIAlertView(title: "Failed", message: msg, delegate: nil, cancelButtonTitle: "Okay") 

     if succeeded == 422 { 
      alert.title = "Failed" 
      alert.message = "Username is already in use. Please selecet another one!" 
     } 

     else if succeeded == 500{ 
      alert.title = "Failed" 
      alert.message = "Internal Server Error. Unable to process Request!" 
     } 

     else if succeeded == 200{ 
      //save to internal DataBase table: User 
      let entityDescription = NSEntityDescription.entityForName("User", inManagedObjectContext: self.managedObjectContext!) 

      let users = User(entity: entityDescription!, insertIntoManagedObjectContext: self.managedObjectContext) 

      users.username = self.userName.text 

      var error: NSError? 

      self.managedObjectContext?.save(&error) 

      if let err = error { 
       println(err.localizedFailureReason) 
      } else { 

       self.userName.text = "" 
       alert.title = "Success" 
       alert.message = "Loading App..." 



       let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) 
       var secondViewController: EveryTimeRun = mainStoryboard.instantiateViewControllerWithIdentifier("everytime") as! EveryTimeRun 

       self.switchRootViewController(secondViewController, animated: true, completion: nil) 




       self.window?.makeKeyAndVisible() 


      } 
     } 

     // Move to the UI thread 
     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
      // Show the alert 
      alert.show() 
     }) 
    } 

Есть ошибка, которую я делаю.

UPDATE:

Я отправляю свою функцию POST. Он может принимать долго:

 func postMulti(apikey: String, contentType: String, payLoad: Dictionary<String,Dictionary<String,String>>, urlString: String, parameter: String, postCompleted : (succeeded: Int, msg: String) ->()){ 

    let joinedUrl = urlString + parameter 
    let url = NSURL(string: joinedUrl) 
    let request = NSMutableURLRequest(URL: url!) 

    var session = NSURLSession.sharedSession() 
    request.HTTPMethod = "POST" 
    request.addValue(contentType, forHTTPHeaderField: "Content-Type") 
    request.addValue(apikey, forHTTPHeaderField: "apikey") 
    var error: NSError? 


    let payLoadJSON = NSJSONSerialization.dataWithJSONObject(payLoad, options: nil, error: &error) 
    request.HTTPBody = payLoadJSON 

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in 
     var strData = NSString(data: data, encoding: NSUTF8StringEncoding) 


     var err: NSError? 
     var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary 
     // Did the JSONObjectWithData constructor return an error? If so, log the error to the console 
     if(err != nil) { 
      //   println(err!.localizedDescription) 
      let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) 

      postCompleted(succeeded: 0, msg: "Portal is not reachable. Please try again later") 
     } 
     else { 
      // The JSONObjectWithData constructor didn't return an error. But, we should still 
      // check and make sure that json has a value using optional binding. 
      if let parseJSON = json { 
       // Okay, the parsedJSON is here, let's get the value for 'success' out of it 
       if let statusCode = parseJSON["statusCode"] as? Int { 

        postCompleted(succeeded: statusCode, msg: "") 
       } 
      } 
      else { 
       // Woa, okay the json object was nil, something went worng. Maybe the server isn't running? 
       let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding) 

       postCompleted(succeeded: 1, msg: "Portal is not reachable. Please try again later") 
      } 
     } 
    }) 

    task.resume() 
} 
+0

, так что вы говорите, что «postMulti» занимает до 15 секунд? – Shai

+0

Я не думаю, что это 'postMulti', который занимает так много времени. Я считаю, что он загружает контроллер корневого представления, который требует времени, потому что «приложение для загрузки» успешно печатается сразу после нажатия кнопки входа. Кроме того, если я заменил текущий контроллер представлений новым быстрым. – kmakma

ответ

0

Я думаю, что самый дорогой в момент эта линия:

self.managedObjectContext?.save(&error) 

Так соу следует сохранить в фоновом режиме или сохранить после включения в viedDidAppear на secondViewController

С MagicalRecord Есть полезный метод saveWithBlock: completion:

Обновление:

Чтобы анимировать вид вы можете использовать этот метод:

var overlaywindow: UIWindow! 
// 

var storyboard = UIStoryboard(name: "Main", bundle: nil) 

    if let popupVC = storyboard.instantiateViewControllerWithIdentifier("everytime") as? EveryTimeRun 
    { 
     var frame = UIScreen.mainScreen().bounds 
     overlayWindow = UIWindow(frame: frame) 

     popupVC.overlayWindow = overlayWindow 
     overlayWindow.windowLevel = UIWindowLevelAlert 
     overlayWindow.rootViewController = popupVC 

     overlayWindow.makeKeyAndVisible() 
     overlayWindow.alpha = 0 

     UIView.animateWithDuration(0.3, animations: 
     { 
      self.overlayWindow.alpha = 1 
     }) 
    } 
+0

, но если я использую следующее в блоке else, то это быстро: self.presentViewController (secondViewController, анимированный: true, завершение: ноль) – kmakma

+0

Ответ недатирован. – ChikabuZ

+0

whit this я получаю сообщение об ошибке: everytimerun не имеет члена с именем overlaywindow – kmakma

0

Я решил эту проблему косвенно. После трассировки кода, я понял, что следующие компоненты вызывает задержку:

  1. метод POST, который был призывающую отдохнуть API - Network Latency
  2. Сохранение имени пользователя в CoreData - Write Latency
  3. Разгрузка существующего (ID : FirstTimeRun) ViewController - Разгрузка Задержка
  4. Загрузка нового tabbedbar (ID: ViewController EveryTimeRun) - Загрузить Задержка

Из них 3 и 4 были самыми высокими.

Итак, чтобы решить эту проблему, я провел некоторое исследование в Интернете и решил, что наилучшей практикой является загрузка контроллера просмотра EveryTimeRun, а затем загрузка в формате FirstTimeRun поверх него, если пользователь еще не выполнил вход в систему. Затем отпустите FirstTimeRun после успешного входа в систему.

Я думаю, что это лучший способ достичь того, что я пытался сделать. Погрузочно-разгрузочные контроллеры просмотра выглядят как взломанные.

Смежные вопросы