2016-08-16 5 views
1

Я хотел бы избежать написания let APIHelper = API() в каждом UIViewController, вместо этого я сделал это:экземпляр класса для всех ViewControllers

extension UIViewController { 
    func APIHelper() -> API { 
    let api = API() 
    return api 
    } 
} 

и теперь он работает как self.APIHelper().callMethod(), но я не совсем уверен, если это так, сделать это. Любые советы по наилучшей практике?

+2

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

+1

как класс APIViewController: UIViewController {let APIHelper = API()} – JuicyFruit

+1

да, что-то в этом роде. и когда вам это нужно, вы просто наследуете этот контроллер. – Miknash

ответ

2

Ваше расширение бесполезно, так как он просто так же, как вызов API()каждый раз:

self.APIHelper().callMethod() 
self.APIHelper().callSecondMethod() //here you created another API instance 

же как

API().callMethod() 
API().callSecondMethod() 

Если API является singletone, идея выглядит нормально, но в стрижа вы обычно создают синглетный со статической константой:

class API { 
    static let sharedAPI = API() 
    //... 
} 

и доступ к ней, как это:

API.sharedAPI.callMethod() 
API.sharedAPI.callSecondMethod() //now called in same API instance 

Если вы не хотите писать API.sharedAPI каждый раз, то вы можете использовать:

Ваше расширение

extension UIViewController { 
    var apiHelper: API {return API.sharedAPI} 
} 

Не рекомендуется, как объяснил @NickCatib.

вид Базовый контроллер

, как @NickCatib предложил (проще с переменной):

class BaseViewController: UIViewController { 
    // some of the code you might need 
    let apiHelper = API.sharedAPI 
} 

Протокол

Если вы используете API времени просматривать контроллерах времени, может быть лучше заявить протокол

protocol APIHelper { 
    var apiHelper: API {get} 
} 

с реализацией по умолчанию

extension APIHelper { 
    var apiHelper: API {return API.sharedAPI} 
} 

и подключить его к ViewController только при необходимости

class ViewControllerThatNeedsAPI: UIViewController, APIHelper { 
    // apiHelper avalible here 
} 

Со всеми тремя способами, вы получаете доступ к API, как это:

apiHelper.callMethod() 
+0

Простое примечание. Синглтон делает это в случае, если у вас есть переменная (переменная), которая в конечном итоге изменится, иначе она будет излишней - это должен быть статический класс. – Miknash

+0

@NickCatib «статический класс» - вы имеете в виду класс, который не может иметь экземпляр? Знаете ли вы какие-либо реализации в быстром? Или, если вы имеете в виду «статический класс», класс без каких-либо хранимых свойств, так что все экземпляры равны на самом деле, - тогда OP может использовать только «API()» всюду, но я думаю, что singleletone лучше, чем многие равные экземпляры , –

+0

Статический класс - класс, где все ее атрибуты и методы статичны - поэтому у вас есть базовый url, установленный один раз и все, и вам не нужно хранить что-либо еще, что является динамическим. На самом деле это будет выглядеть примерно так: Service.API(). – Miknash

1

Как насчет какого-то контроллера базового вида, где вы можете продлить это объявление? Таким образом, у всех контроллеров вашего вида есть такая функция, даже если она вам не нужна.

Это будет идти как

class BaseViewController: UIViewController { 
    // some of the code you might need 
    func APIHelper() -> API { 
    let api = API() 
    return api 
    } 
} 

И позже:

class ViewControllerThatNeedsAPI : BaseViewController { 
    // You have it here 
} 

Другой подход, который я использую, чтобы иметь сервис/менеджер для вызовов API, который обрабатывает это, и отправить все необходимые данные через обработчик делегирования/NSNotification/завершения. Таким образом, ваш код будет более чистым и легче тестировать (если вы проводите тесты). Если вы держите все в контроллере представления, вы сломаете SRP. Этими менеджерами являются PONSO - Обычные старые ns объекты. Вы можете использовать тот же путь, что и для контроллеров представлений, и иметь базовый сервис с URL-адресом API, базовые вещи, которые необходимо переоценить. После этого вы просто внедряете сервис и вызываете его по мере необходимости - в зависимости от реализации есть некоторая функция для отражения данных в UI.

Смежные вопросы