Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios swift中的依赖倒置_Ios_Swift_Dependency Inversion - Fatal编程技术网

Ios swift中的依赖倒置

Ios swift中的依赖倒置,ios,swift,dependency-inversion,Ios,Swift,Dependency Inversion,嗨,我有个问题要问开发者,我在读一本来自big nerd ranch的iOS编程书。我感兴趣的是如何构造和技术来创建一个应用程序。我试图实现它,它是一个依赖项反转,代码是这样的 这是本书中的应用程序内代码委托 let rootViewController = window!.rootViewController as! UINavigationController let photosViewController = rootViewController.topViewControlle

嗨,我有个问题要问开发者,我在读一本来自big nerd ranch的iOS编程书。我感兴趣的是如何构造和技术来创建一个应用程序。我试图实现它,它是一个依赖项反转,代码是这样的

这是本书中的应用程序内代码委托

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列表,并且在那里您还可以设置依赖项。不客气。也请向上投票,以便有相同问题的人可以很容易地看到答案。