Инверсия зависимости в быстром

Привет, у меня есть вопрос для разработчика, я читал книгу по программированию для 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)")
        }
     }
  }
}

и это класс хранилища фотографий, который используется для кода инверсии зависимости

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)
    }
}

Я спрашиваю, если у меня есть контроллер панели вкладок и, скажем, 2 контроллера просмотра, один из них выбирает новостные данные, а другой контроллер - данные о погоде. как я могу реализовать эту инверсию зависимостей, так как корневой контроллер представления в делегате приложения будет контроллером панели вкладок, поэтому я путаю его реализацию? Так как в книге используется только один вид контроллера.

1 ответ

Решение

Имейте в виду, что это взлом, и, по моему мнению, это не должно быть сделано так, как зависимости должны быть объявлены в init, Но потому что вы, вероятно, создаете TabBar из раскадровки. У вас есть только эта опция, которая получает TabBar из окна. и TabBarController имеет массив viewControllers, которые формируют TabBar. Вам просто нужно перебрать и попытаться разыграть их как PhotoViewController, Если это так, то вы устанавливаете магазин:

let rootViewController = window!.rootViewController as! UITabBarController

for viewController in rootViewController.viewControllers {
    switch viewController {
    case let photoViewController as PhotoViewController:
        photoViewController.store = PhotoStore()
    default:
        break
    }
}
Другие вопросы по тегам