I am following this example to implement clean architecture in my iOS app.
class CreateOrderConfigurator
{
private static var __once: () = {
//ERROR - use of unresolved identifier 'Static'
Static.instance = CreateOrderConfigurator()
}()
// MARK: Object lifecycle
class var sharedInstance: CreateOrderConfigurator
{
struct Static {
static var instance: CreateOrderConfigurator?
static var token: Int = 0
}
_ = CreateOrderConfigurator.__once
return Static.instance!
}
// MARK: Configuration
func configure(_ viewController: CreateOrderViewController)
{
let router = CreateOrderRouter()
router.viewController = viewController
let presenter = CreateOrderPresenter()
presenter.output = viewController
let interactor = CreateOrderInteractor()
interactor.output = presenter
viewController.output = interactor
viewController.router = router
}
}
I get an error saying use of unresolved identifier 'Static'. How do I solve this?
PS : I am new to iOS and Swift 3.
A singleton is very simple in Swift
Replace
private static var __once: () = {
//ERROR - use of unresolved identifier 'Static'
Static.instance = CreateOrderConfigurator()
}()
// MARK: Object lifecycle
class var sharedInstance: CreateOrderConfigurator
{
struct Static {
static var instance: CreateOrderConfigurator?
static var token: Int = 0
}
_ = CreateOrderConfigurator.__once
return Static.instance!
}
with
static let sharedInstance = CreateOrderConfigurator()
Related
I'm trying to pass data between viewControllers, but something seems wrong.
The first viewController I want to set the "Bool" to the protocol function to be able to recover in the other screen. What am I doing wrong, I always used protocols but at this time I got in trouble.
That's how I'm doing that:
//
// ComboBoxNode.swift
//
import Foundation
import SWXMLHash
protocol ComboBoxNodeDelegate {
func getCustomOption(data:Bool)
}
class ComboBoxNode: FormControlNode, IFormControlDataSource {
var listType: String?
var dataSource: String?
var dataSourceValue: String?
var dataSourceText: String?
var hasCustomOption:Bool?
var customOptionText: String?
var ctrlDataSourceType: String?
var parameters = [ParameterNode]()
var staticList: FormControlStaticListNode?
var delegate:ComboBoxNodeDelegate?
override init(indexer: XMLIndexer) {
super.init(indexer: indexer)
guard let element = indexer.element else {
preconditionFailure("Error")
}
let isCustomOption = element.bool(by: .hasCustomOption) ?? hasCustomOption
if isCustomOption == true {
self.delegate?.getCustomOption(data: hasCustomOption!)
}
self.readFormControlDataSource(indexer: indexer)
}
override func accept<T, E: IViewVisitor>(visitor: E) -> T where E.T == T {
return visitor.visit(node: self)
}
}
That's how I'm trying to recover on next screen:
// FormPickerViewDelegate.swift
import Foundation
import ViewLib
import RxSwift
class FormPickerViewDelegate: NSObject {
var items = Variable([(value: AnyHashable, text: String)]()) {
didSet {
PickerNodeDelegate = self
self.setDefaultValues()
}
}
private var controlViewModel: FormControlViewModel
private var customText:Bool?
private var PickerNodeDelegate:ComboBoxNodeDelegate?
init(controlViewModel: FormControlViewModel) {
self.controlViewModel = controlViewModel
}
func getItemByValue(_ value: Any) -> (AnyHashable, String)? {
if value is AnyHashable {
let found = items.value.filter {$0.value == value as! AnyHashable}
if found.count >= 1 {
return found[0]
}
}
return nil
}
}
extension FormPickerViewDelegate:ComboBoxNodeDelegate {
func getCustomOption(data: Bool) {
customText = data
}
}
Instead of setting PickerNodeDelegate = self in didSet {} closure
var items = Variable([(value: AnyHashable, text: String)]()) {
didSet {
PickerNodeDelegate = self
self.setDefaultValues()
}
}
Assign it in your init() function instead
init(controlViewModel: FormControlViewModel) {
self.controlViewModel = controlViewModel
PickerNodeDelegate = self
}
Note, your should declare your delegate to be weak also, since it's a delegate, your protocol should conform to be a class type in order to be weakified.
protocol ComboBoxNodeDelegate: class
...
weak var delegate: ComboBoxNodeDelegate?
Here is an example, hope it helps!
protocol ComboBoxNodeDelegate {
func getCustomOption(data:Bool) -> String
}
class ViewOne:ComboBoxNodeDelegate {
var foo:Bool = false
var bar:String = "it works!"
/** Return: String */
func getCustomOption(data:Bool) -> String { //conform here to protocol
// do whatever you wanna do here ...example
self.foo = data // you can set
return bar // even return what you want
}
//initialize
func initalizeViewTwo() {
let v2 = ViewTwo()
v2.delegate = self //since `self` conforms to the ComboBoxNodeDelegate protcol you are allowed to set
}
}
class ViewTwo {
var delegate:ComboBoxNodeDelegate?
func getCustomOption_forV1() {
let view2_foo = delegate.getCustomOption(data:true)
print(view2_foo) // should print "it works!"
}
}
All parameters passed around in Swift are constants -- so you cannot change them.
If you want to change them in a function, you must declare your protocol to pass by reference with inout:
protocol ComboBoxNodeDelegate {
func getCustomOption(data: inout Bool)
}
Note: you cannot pass a constant (let) to this function. It must be a variable -- which I see you are doing!
I am trying to DRY up my app by creating a Firebase DataService but I don't know what type to cast for Auth.auth(). I looked at the Source Code Definition but it is in Objective C which I do not understand. Is extracting Auth.auth() even possible?
Here is what I have:
let FB_AUTH = Auth.auth()
let DB_BASE = Database.database().reference()
let FB_STORAGE = Storage.storage().reference()
class FBData {
static let fbi = FBData()
//MARK: PROPERTIES
private var _FB_AUTH = FB_AUTH
private var _REF_BASE = DB_BASE
private var _STORAGE_BASE = FB_STORAGE
private var _REF_USERS = DB_BASE.child("users")
//MARK: PRIVATE GETTERS
var FB_AUTH: NSObject {
return _FB_AUTH
}
var REF_BASE: DatabaseReference {
return _REF_BASE
}
var STORAGE_BASE: StorageReference
{
return _STORAGE_BASE
}
var REF_USERS: DatabaseReference {
return _REF_USERS
}
}
Looking in the source, as you said, I see:
+ (FIRAuth *)auth NS_SWIFT_NAME(auth());
(FIRAuth *) is the return type. So Auth.auth() is of type FIRAuth (Auth in Swift) which inherits from NSObject
NS_SWIFT_NAME(Auth)
#interface FIRAuth : NSObject
So, i am creating a Singleton class as below, and i need few instance variables in this class, such that any team member can access the instance variable and get the values. To do that, i will need to initialize these instance variables to a certain value at the beginning itself.
But i get a compilation error, saying "missing argument for parameter 'doesValueExists' in call".
What exactly i m doing wrong here ?
class ABC_Util {
private var doesValueExists: Bool
private var arrValues: NSMutableArray?
class var sharedInstance: ABC_Util {
struct ABC_UtilSingleton {
static let instance = ABC_Util()
}
return ABC_UtilSingleton.instance
}
init(doesValueExists: Bool, arrValues: NSMutableArray?) {
self.doesValueExists = self.checkValueExists()
self.arrValues = self.getArrayOfValues()
}
//method
internal func checkValueExists() -> Bool {
}
//method
internal func getArrayOfValues() -> NSMutableArray? {
}
}
Your initializer for ABC_Util is declared as:
init(doesValueExists:Bool, arrValues:NSMutableArray?) {
Therefore you cannot say
static let instance = ABC_Util()
The expression ABC_Util() would correspond to an initializer with no parameters, and you do not have such an initializer. You must say:
static let instance = ABC_Util(doesValueExists:someBool, arrValues:someArray)
(with appropriate values, of course).
You have to use your initializer in order to initialize your variables.
class ABC_Util {
private var doesValueExists:Bool
private var arrValues:NSMutableArray?
class var sharedInstance: ABC_Util
{
struct ABC_UtilSingleton
{
static let instance = ABC_Util(doesValueExists: true, arrValues: nil)
}
return ABC_UtilSingleton.instance
}
init(doesValueExists:Bool, arrValues:NSMutableArray?) {
self.doesValueExists = doesValueExists
self.arrValues = arrValues
}
//method
internal func checkValueExists()-> Bool
{
return true
}
//method
internal func getArrayOfValues()-> NSMutableArray?
{
return nil
}
}
And I recommend you to change your singleton declaration to the suggested syntax
static let sharedInstance: ABC_Util = ABC_Util(doesValueExists: true, arrValues: nil)
You could use as below.
class ABC_Util {
private var doesValueExists:Bool = false
private var arrValues:NSMutableArray?
class var sharedInstance: ABC_Util {
struct ABC_UtilSingleton {
static let instance = ABC_Util(doesValueExists: false, arrValues: ["a", "b", "c"])
}
return ABC_UtilSingleton.instance
}
init(doesValueExists:Bool, arrValues:NSMutableArray?) {
self.doesValueExists = self.checkValueExists()
self.arrValues = self.getArrayOfValues()
}
//method
internal func checkValueExists()-> Bool{
return self.doesValueExists
}
//method
internal func getArrayOfValues()-> NSMutableArray?{
return arrValues
}
}
i got the solution, when i tried this, worked fine!
class ABC_Util {
var doesValueExists:Bool = false
var arrValues:NSMutableArray? = nil
class var sharedInstance: ABC_Util
{
struct ABC_UtilSingleton
{
static let instance = ABC_Util()
}
return ABC_UtilSingleton.instance
}
init() {
self.doesValueExists = self.checkValueExists()
self.arrValues = self.getArrayOfValues()
}
//method
internal func checkValueExists()-> Bool
{
//return true/false
}
//method
internal func getArrayOfValues()-> NSMutableArray?
{
//return array/nil
}
}
This question already has answers here:
Using a dispatch_once singleton model in Swift
(30 answers)
Closed 6 years ago.
In a class I would previously create a shared instance like so:
class MenuConfigurator
{
// MARK: Object lifecycle
class var sharedInstance: MenuConfigurator
{
struct Static {
static var instance: MenuConfigurator?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = MenuConfigurator()
}
return Static.instance!
}
}
It seems the Swift 3.0 migration tool has changed the block of code to:
class MenuConfigurator
{
private static var __once: () = {
Static.instance = MenuConfigurator()
}()
// MARK: Object lifecycle
class var sharedInstance: MenuConfigurator
{
struct Static {
static var instance: MenuConfigurator?
static var token: Int = 0
}
_ = MenuConfigurator.__once
return Static.instance!
}
}
I am getting the error Use of unresolved identifier Static. What is happening here? Why has the new var private static var __once been created?
dispatch_once_t has been dropped in Swift 3.
The recommended way (at least since Swift 2) to create a singleton is simply
class MenuConfigurator
{
static let sharedInstance = MenuConfigurator()
}
let configurator = MenuConfigurator.sharedInstance
Forget the suggestion of the migrator.
I'm trying to implement an image downloader class. It's a singleton implementation. The idea is to ask the instance to download an image and register as an observer for that image download. This is what I came up with so far:
public protocol ImageDownloaderDelegate {
func imageDownloadFinished(success: Bool)
}
public class ImageDownloader {
var list: [Int64] = []
var observer: [Int64:[ImageDownloaderDelegate]] = [:]
var downloading: Bool = false
public func downloadImageWithId(immutableId: Int64, delegate: ImageDownloaderDelegate) {
// Add Id to download list
if (!contains(list, immutableId)) {
list.append(immutableId)
}
// Add Observer
var observerList = observer[immutableId]
if (observerList == nil) {
observerList = [delegate]
} else if (!contains(observerList, delegate)) {
observerList!.append(delegate)
}
observer[immutableId] = observerList
// Start to download
if (!downloading) {
self.downloadNextImage()
}
}
private func downloadNextImage() {
...
}
/// A shared instance of the class
public class var defaultImageDownloader: ImageDownloader {
struct Singleton {
static let instance = ImageDownloader()
}
return Singleton.instance
}
}
I get the following error:
'ImageDownloaderDelegate' is not convertible to 'S.Generator.Element -> L'
Any help is much appreciated
You're not passing the correct arguments to the contains function, which expects a collection and a predicate (closure).
You need to do
public protocol ImageDownloaderDelegate : class {
func imageDownloadFinished(success: Bool)
}
public class ImageDownloader {
var list: [Int64] = []
var observer: [Int64:[ImageDownloaderDelegate]] = [:]
var downloading: Bool = false
public func downloadImageWithId(immutableId: Int64, delegate: ImageDownloaderDelegate) {
// Add Id to download list
if (!contains(list, immutableId)) {
list.append(immutableId)
}
// Add Observer
var observerList = observer[immutableId]
if (observerList == nil) {
observerList = [delegate]
} else if !contains(observerList!, { observer in observer === delegate }) {
observerList!.append(delegate)
}
observer[immutableId] = observerList
// Start to download
if (!downloading) {
self.downloadNextImage()
}
}
private func downloadNextImage() {
...
}
/// A shared instance of the class
public class var defaultImageDownloader: ImageDownloader {
struct Singleton {
static let instance = ImageDownloader()
}
return Singleton.instance
}
}