Инверсия зависимости в быстром - PullRequest
0 голосов
/ 25 февраля 2019

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

0 голосов
/ 25 февраля 2019

Имейте в виду, что это хак, и, по моему мнению, этого не следует делать, так как зависимости должны быть объявлены в 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...