等待网络调用完成的正确性 - iOS

Rightness of waiting for a network call to complete - iOS

我对用户的用户体验很好奇,他们等待网络调用完成而不是取消现有的非确定性请求。让我添加更多上下文。我正在为以后使用的应用程序预取数据。当用户点击按钮时,我们使用此数据加载屏幕。我们不想向用户显示微调器并等待网络调用完成,而是希望为他们提供更好的用户体验。

class TestInteractor {
   var currentTask: HTTPTask?
   var content: SomeContent?

   func getData(_ id: String, completion: Result<SomeContent, Error>) {

      currentTask = URLSession.shared().dataTask(with: request) { 
          // check for no error
          // set content here

      }
   }

   var hasContent: Bool { 
      return content != nil
   }
}

问题来了,如果预取仍在进行中(由于网络不佳),我应该让用户等到此调用完成还是取消任务并重新启动新调用。

取消现有的网络呼叫可以如下实现:

func getData(_ id: String) {
  if let task = currentTask { 
      task.cancel()
      currentTask = nil
  }

  // Continue with a new network call
}

或者我应该在 TestInteractor 中添加一个新的 属性 并检查网络是否仍在进行中并等待?

var isNetworkCallInProgress: Bool {
    return currentTask?.state == running
}

您可以给用户一个选择,您可以添加一个刷新按钮来重置呼叫或让他们等待。

如果你想问他们它是否在工作,你可以只推送一个警报,询问他们是否想刷新呼叫,同时 运行 在后台进行预取。

let alert = UIAlertController(title: "Message Title", message: "body text", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "button", style: .default, handler: nil))
                self.present(alert, animated: true, completion: nil)

这是警报代码。我会亲自检查并查看该过程是否需要很长时间,然后发出警报,要求刷新或等待。

网络请求尚未完成的原因可能有很多;您的服务器可能有点不堪重负;客户端的网速可能有点慢。中止工作并重新开始可能是一种浪费。谁说重新启动任务将改变当前的任何障碍。

我会说等待 运行 任务完成。如果预取在我们需要之前完成,那太好了,预取节省了时间。但是如果在我们需要它的时候它还没有完成,如果你让它完成,那仍然会节省时间而不是重新启动它(重新启动的任务不会仅仅因为我们重新启动它就神奇地比前一个更快)所以预取在这种情况下也很有用。因此,通过允许请求完成,您可以最大限度地利用预取机制。另外,如果您因为预取无法及时完成而选择重新启动任务,如果您的平均用户实际上比该请求的平均服务时间更快怎么办?大声笑谁知道呢,在一般情况下,您最终可能会将服务器负载加倍。更好的是你有一个与这样的东西分离的设计。

首先,您的应用有一个网络 activity 指示器。统计你开始了多少个网络任务,完成了多少个,当计数从 0 变为 1 或从 1 变为 0 时,打开或关闭网络 activity 指示灯。这表明网络 activity ] 很友好地。

其次,在您的数据模型中,您将拥有具有正确数据的项目、正在加载的项目和未加载的项目。编写代码来显示每种项目。当网络请求完成时,它会更新您的数据模型,并重新绘制相应的项目。