Ios swift中的依赖倒置
嗨,我有个问题要问开发者,我在读一本来自big nerd ranch的iOS编程书。我感兴趣的是如何构造和技术来创建一个应用程序。我试图实现它,它是一个依赖项反转,代码是这样的 这是本书中的应用程序内代码委托Ios swift中的依赖倒置,ios,swift,dependency-inversion,Ios,Swift,Dependency Inversion,嗨,我有个问题要问开发者,我在读一本来自big nerd ranch的iOS编程书。我感兴趣的是如何构造和技术来创建一个应用程序。我试图实现它,它是一个依赖项反转,代码是这样的 这是本书中的应用程序内代码委托 let rootViewController = window!.rootViewController as! UINavigationController let photosViewController = rootViewController.topViewControlle
let rootViewController = window!.rootViewController as! UINavigationController
let photosViewController = rootViewController.topViewController as! PhotoViewController
photosViewController.store = PhotoStore()
这是photoViewController类
class PhotoInfoViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
var photo: Photo! {
didSet {
navigationItem.title = photo.title
}
}
var store: PhotoStore!
override func viewDidLoad() {
super.viewDidLoad()
store.fetchImage(for: photo) { (result) in
switch result {
case let .success(image):
self.imageView.image = image
case let .failure(error):
print("Error fetching image for photo: \(error)")
}
}
}
}
这是用于依赖项反转代码的photo store类
enum ImageResult {
case success(UIImage)
case failure(Error)
}
enum PhotoError: Error {
case imageCreationError
}
enum PhotoResult {
case success([Photo])
case failure(Error)
}
class PhotoStore {
private let session: URLSession = {
return URLSession(configuration: .default)
}()
let imageStore = ImageStore()
func fetchInterestingPhoto(completion: @escaping (PhotoResult) -> Void) {
let url = FlickerAPI.interestingPhotoURL
let request = URLRequest(url: url)
let task = session.dataTask(with: request) { (data, response, error) in
let result = self.processPhotosRequest(data: data, error: error)
OperationQueue.main.addOperation {
completion(result)
}
}
task.resume()
}
private func processPhotosRequest(data: Data?, error: Error?) -> PhotoResult {
guard let jsonData = data else { return .failure(error!) }
return FlickerAPI.photos(fromJSON: jsonData)
}
func fetchImage(for photo: Photo, completion: @escaping (ImageResult) -> Void) {
let photoKey = photo.photoID
if let image = imageStore.image(forKey: photoKey) {
OperationQueue.main.addOperation {
completion(.success(image))
}
return
}
let photoURL = photo.remoteURL
let request = URLRequest(url: photoURL)
let task = session.dataTask(with: request) { (data, response, error) in
let result = self.processImageRequest(data: data, error: error)
if case let .success(image) = result {
self.imageStore.setImage(image, forKey: photoKey)
}
OperationQueue.main.addOperation {
completion(result)
}
}
task.resume()
}
private func processImageRequest(data: Data?, error: Error?) -> ImageResult {
guard
let imageData = data,
let image = UIImage(data: imageData)
else {
// Couldn't create an image
if data == nil {
return .failure(error!)
} else {
return .failure(PhotoError.imageCreationError)
}
}
return .success(image)
}
}
我要问的是,如果我有一个选项卡栏控制器,让我们假设两个视图控制器,其中一个是获取新闻数据,另一个是获取天气数据。既然app delegate中的根视图控制器将是选项卡栏控制器,那么我如何实现这种依赖关系反转呢?这就是为什么我混淆了如何实现它?由于本书仅使用单个视图控制器 请记住,这是一种黑客行为,在我看来,不应该这样做,因为依赖项应该在
init
中声明。但因为您可能是从故事板创建选项卡栏。您只有从窗口获取选项卡栏的选项。而TabBarController
有一个组成TabBar的viewControllers数组。您只需迭代并尝试将它们转换为PhotoViewController
。如果是,则设置存储:
let rootViewController = window!.rootViewController as! UITabBarController
for viewController in rootViewController.viewControllers {
switch viewController {
case let photoViewController as PhotoViewController:
photoViewController.store = PhotoStore()
default:
break
}
}
你对依赖倒置有什么理解?因为我在代码中没有看到任何内容。@我看到的是应用程序中的照片存储委托需要从根视图控制器中存储PhotoStore(),它可以稍后通过在photoViewController中创建一个类型来使用。我不明白的是,如果我在app delegated中将我的tab-bar控制器作为根控制器,我如何实现它?你可以将tab-bar控制器子类化,这样就可以工作?@KaneCheshire那么另一个控制器需要是一个超级类?我还是不明白抱歉,哈哈,我明白了。因此,如果用户选项卡是视图控制器中的一个,则根视图控制器将更改Dependent user选项卡。如果我以编程方式使用tabbarcontroller而不使用故事板,这也可以吗?不,
rootViewController
不会改变。rootViewController
是一个UITabBarController
。但是UITabBarController
有一个viewControllers
数组,这些数组在情节提要中或以编程方式定义。但是,如果您以编程方式执行此操作,您就不需要这样做,因为在某个时候,您可以在该选项卡栏中设置ViewController列表,并且在那里您还可以设置依赖项。不客气。也请向上投票,以便有相同问题的人可以很容易地看到答案。