- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
问题:我想在 Swift 中开发一个 iOS 应用程序,它在登录后立即执行初始加载。序列(通过 NSURLSession 的基于 REST 的调用)看起来像这样:
基本上,我想找到一种优雅的方式来实现这样的序列。
方法:首先,我只是在另一个的完成处理程序中调用新的(依赖的)REST 调用。但是如果需要执行很多调用并且依赖级别比上面描述的更多,那么代码看起来有点乱......
我参加了关于 NSOperations 的 WWDC 2015 session ,认为这可能是个好主意,因为有些人可以非常容易地定义依赖关系。不幸的是,Apple 提供的示例代码没有给出上述问题的答案……是吗(我没明白?)?在玩操作时,我无法确定如何在创建不同操作时解决初始化问题(LoginOperation、CountryOperation(依赖于 LoginOperation)、ProductOperation(依赖于 CountryOperation)等)
我发现这些帖子非常有帮助,但我仍然不了解如何最好地解决我描述的问题: How To Download Multiple Files Sequentially using NSURLSession downloadTask in Swift Chaining NSOperation
: Pass result from an operation to the next one NSURLSession with NSBlockOperation and queues
困难:在另一个操作 A 成功完成并返回将由操作 B 使用的结果时初始化操作 B。
最佳答案
如果仍然相关,我可能会有答案。
这里的问题是您试图将初始化推迟到第一个操作完成。那是死路一条。操作旨在尽早创建,并使用依赖项保证顺序。
那么让我们讨论一些解决这个极其常见问题的方法。
(您可以注意到这些示例是以 WWDC session 风格编写的。这实际上是因为我使用了基于该演讲的 Operations library。如果您对基于操作的架构感兴趣,请看一看。 )
这基本上意味着,对于您的示例,您有一些 UserController
,您将其实例传递给 LoginOperation
和 CountryOperation
. LoginOperation
将 userId
写入该 Controller ,CountryOperation
从中读取:
class UserController {
var userID: String?
}
class LoginOperation: Operation {
let userController: UserController
init(userController: UserController) {
self.userController = userController
}
override func execute() {
// do your networking stuff
userController.userID = receivedUserID
finish()
}
}
class CountryOperation: Operation {
let userController: UserController
init(userController: UserController) {
self.userController = userController
}
override func execute() {
let userID = userController.userID
// continue
}
}
然后:
let queue = OperationQueue()
let userController = UserController()
let login = LoginOperation(userController: userController)
let country = CountryOperation(userController: userController)
country.addDependency(login)
queue.addOperation(login)
queue.addOperation(country)
该解决方案的问题在于它非常复杂且难以测试。而且 Swift 也不太喜欢可变的共享状态。
好吧,这不是显而易见但非常优雅的解决方案。如您所见,值在初始化时被复制。我们真正需要的是在执行时检索所需的值(与前面的示例一样),但不需要如此紧密的耦合。好吧,这很容易完成 - 只需将一个函数传递给初始化器即可!
class LoginOperation: Operation {
private(set) var userID: String?
override func execute() {
// do your networking stuff
let receivedUserID = "1"
userID = receivedUserID
finish()
}
}
class CountryOperation: Operation {
private let getUserID: () -> String
init(getUserID: () -> String) {
self.getUserID = getUserID
}
override func execute() {
/* Because this operation depends on `LoginOperation`,
`getUserID()` is called after `LoginOperation` is finished. */
let userID = self.getUserID()
// continue
}
}
然后:
let queue = OperationQueue()
let login = LoginOperation()
// Force-unwrap is no good, of course, but for this example it's ok
let country = CountryOperation(getUserID: { login.userID! })
country.addDependency(login)
queue.addOperation(login)
queue.addOperation(country)
如您所见,没有紧耦合,没有共享的可变状态(CountryOperation
只能读,不能写——这很好)。而且它的测试非常容易:只需将任何你想要的传递给 CountryOperation
初始化器,你根本不需要 LoginOperation
来测试它!
实际上,通过这种方法,NSOperation
的主要目标已经实现:与众不同的抽象工作。 CountryOperation
本身对 LoginOperation
以及任何其他共享实例一无所知。
实际上,我在我的项目中经常使用这种方法,而且效果惊人。
如果您还有任何问题,请回复:)
关于ios - 与 NSOperation 和 NSOperationQueue (Swift) 相互依赖的 NSURLSession 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35035478/
我编写了一个提供一些数据的 REST 服务。它受密码保护。 我正在尝试编写一个后台进程来获取数据并将其填充到我在应用程序中拥有的 sqlLite 数据库中。 我最初是在没有身份验证的情况下使用的: -
我想要一个 API key 并验证用户身份。我在控制台中看到消息“ session URL 任务成功:HTTP 200”。不幸的是,我总是收到页面“{”消息“:”的消息。此请求“}”的授权已被拒绝。我
我为 NSURLSession 创建了类别,然后我遇到了一个问题。在 iOS 7 中,[[NSURLSession sharedSession] isKindOfClass:[NSURLSession
如何从 NSHTTPCookieStorage.sharedHTTPCookieStorage 中删除所有 cookie?我知道删除单个指定 cookie 的唯一方法,但是,这些 cookie 是由
我正在尝试在应用程序进入后台(例如从主页按钮按下)的情况下正确处理进程内 NSURLSessionTasks。我目前正在采用将进程中的任务复制到后台队列的方法(请参见下面的代码)。然而,我发现后台任务
我是 objective-c 中的新手,使用 iOS 9 Xcode 7.2 并收到此警告“'initWithRequest:delegate:'已弃用:在 iOS 9.0 中首次弃用 - 使用 NS
当我导入 Gmail API 的 GTL.xcodeproj 并运行它时出现上述错误。我正在使用 Xcode 7.1 beta 并且在 Gmail API 二进制文件的头文件中出现了很多错误我们不推荐
我在我的 iOS 应用程序中使用 Alamofire 进行网络连接。我需要在 iOS 7+ 中运行这个应用程序。我要在状态栏中指示网络事件 ,所以我创建了这个结构: struct ActivityMa
我需要从服务器下载视频并保存视频以供稍后观看。 所以我需要下载视频并将其使用自定义名称保存在应用程序的文件系统中,到目前为止我可以下载数据(我猜)但无法存储它。 不,我不想使用额外的扩展框架或其他什么
在一个小型 iOS 应用程序中,我需要从服务器检索一些 JSON(类似于 DNS 请求),并使用此响应来发起进一步的连接。为此,我有一个使用 NSURLSession 处理 JSON 请求的对象。该对
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
当我尝试在网络离线(飞行模式)时启动基本的 NSURLSession 传输时,使用 NSURLSessionConfiguration defaultSessionConfiguration 和 ep
我曾经用 NSURLConnection 做我想做的事. 我会创建一个新的自定义 NSOperation对象 设置我的 NSMutalbeRequest当准备好触发operation女巫会排队操作..
我创建了一个下载任务。我已经使用cancelByProducingResumeData在应用程序中取消了任务,并将其保存到磁盘。当用户重新启动应用程序并单击“恢复”按钮时,我再次通过self.down
即使在使 NSURLSession 无效后,使用 Instruments 运行配置文件,一些名为 TubeManager、HTTPConnectionCache 和 HTTPConnectionCac
我有一段普通的代码,我几乎在我的代码中到处使用: let configuration = URLSessionConfiguration.default let session = URLSessio
我希望有人能够帮助我理解在我的 WatchOS 2 应用程序中尝试实现 NSURLSession 时遇到的问题。 无论出于何种原因,我收到错误; Error Domain=NSCocoaErrorDo
我正在尝试使用 NSURLSession 从 URL 获取 ID,但是 let task = NSURLSession.... 和 task.resume 之间的代码 永远不会执行(我在里面放置了一个
我正在尝试使用 NSURLSession 发出 HTTPRequest。当我设置完整的 url 时,请求返回正确的数据,但是当使用参数时 (NSJSONSerialization.dataWithJS
我是这方面的新手,但过去常常在这里搜索特定的东西,并且由于我找不到特定的答案,也许这里有人可以提供帮助。 我基本上是在学习和构建一个应用程序。 目前我已经构建登录、注册 View Controller
我是一名优秀的程序员,十分优秀!