How everyone manage their firestore paths? - google-cloud-firestore

I am using cloud function and client access firestore.but all paths string are hardcode in code. once I changed a collection name I need to change everywhere that the code access same collection. Anyone have a better way to manage them?

Instead of literal strings everywhere, declare a global constant. For example, the usual thing in Swift is a struct or enum with a constant static property.
struct Constants {
static let key = "whatever"
}
Now you can say Constants.key anywhere in your program. Any computer language will have something equivalent.

Related

Swift keyPath vs protocol

I understand the basic idea of keyPaths but I do not understand its use cases. If you already know the type of the instance, you can access their properties easily. If you don’t, protocol already supports read-only, read-write properties. Can someone explain me what I am missing? Anything that we can’t do with protocols but keyPaths or when keypaths are better than protocols?
If you already know the type of the instance, you can access their properties easily. If you don’t, protocol already supports read-only, read-write properties. Can someone explain me what I am missing?
What you're missing is a sense of what's unknown.
In both your sentences you speak of knowing what the instance's properties are. That's not the problem key paths solve. Key paths have nothing to do with knowing the type; they are not in any kind of opposition to types or protocols. On the contrary, before you can use a key path, you have to know exactly what the instance's properties are.
Key paths are for when what is unknown is which property to access. They provide a way to pass a property reference so that someone else can be told to access that property.
For example, here's a Person type:
struct Person {
let firstName : String
let lastName : String
}
And here is a function that sorts an array of Persons by either the firstName or the lastName, without knowing which one to sort by:
func sortArrayOfPersons(_ arr:[Person], by prop: KeyPath<Person, String>) -> [Person] {
return arr.sorted { $0[keyPath:prop] < $1[keyPath:prop] }
}
A key path is how you tell this function what property to use as a basis for sorting.

Swift 4 statically get value of model property name

When using Swift 3, I was defining my model like so
class Model: NSObject {
var prop1: String
}
When I wanted to access the static string value of the property name prop1, I would use let sad = #keyPath(Model.prop1) and it would give me "prop1" printed out. Happy days.
The problem is, that since upgrading to Swift 4, I am having trouble doing the above. I see in other posts that we can use the new \Model.prop1 syntax but that seems to be providing the value of property rather than the string representation of the name.
I am also refactoring out the need for NSObject on my Swift models, but I would have thought I can still get this functionality.
Any help here would be appreciated!
Swift properties do not necessarily retain the strings of the property names at runtime. Therefore, if the Swift key path syntax were able to give you this string value, it would only be able to be used on NSObject-derived classes. The Swift key path syntax doesn't only work with those, though; it can also be used to refer to properties of non-#objc classes and structs. Therefore, this is not possible. The #keyPath syntax remains available, however, to get the string key path of an Objective-C property.

Swift: access level between `private` and `internal`?

In my Swift code, I often use the private modifier to limit the visibility of helper classes. For example, in one file, I'll have a GridController and a GridControllerModel.
The GridController (the UI) should be accessible to the rest of the application, but the model class is wholly internal and should never be accessed by the rest of the application.
I can address this in Swift by making both classes private and keeping them in the same file. But this gets unwieldy as classes get bigger. What I'd like to do is keep each class in a separate file (for programming convenience), but prevent access to the model class anything but GridController (for information hiding purposes).
Is there any way to do this in Swift?
As others have said, there is no way to do exactly what you want today in Swift.
One alternative is to use an extension in another file to add GridControllerModel as a nested subtype of GridController. e.g.
//GridControllerModel.swift
extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}
This allows your GridController class in its own separate file to declare something like:
var model = GridControllerModel()
However, the rest of the application can still access the GridControllerModel type like this:
//SomeOtherClass.swift
var nested = GridController.GridControllerModel()
So, you do achieve some separation by making the model type a subtype of GridController, but it isn't true access control. On the plus side, it will not appear in code completion outside of the GridController class as "GridControllerModel", you would need to first type "GridController" and then "." to see the subtype "GridController.GridControllerModel"
It's also worth noting that an additional access control level is currently under review and likely to be in the next version of Swift (3.0) :
https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md
Assuming this proposal is accepted and implemented, you would be able to update your declared subtype like this:
//GridControllerModel.swift
local extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}
(Note the "local" keyword above now). This would make the GridControllerModel type invisible and inaccessible to all classes except GridController and any extensions of GridController.
So, I would recommend that you consider this nested subtype approach today, because when Swift 3.0 arrives later this year, it's likely to support what you want by simply adding a keyword in front of your subtype declaration. And in the meantime, you get some of the separation you want as well.
No, there isn't an access modifier that restricts visibility to only a certain set of files. But you probably don't need that.
What does exist:
private: restricts visibility to within the same source file.
internal: restricts visibility to within the same module.
If you're building a piece of software that's too big for one source file, but both defines an outward-facing interface and internal details that should stay hidden from clients of that interface... then you're probably working at a level where it's appropriate to build a framework. Your framework can then define features that are internal for its use only and separate from the public interface it exposes to clients.

Swift Instance Variable Underscore Prefix?

Did Swift drop the underscore-prefix convention for instance variables, e.g., _window? If so, why?
Apple still uses _ in its Xcode boilerplate code as a convention for a non-public variable. You'll see a pattern like such:
class Foo {
var _bar : Bar? = nil
var bar : Bar {
if _bar == nil {
/* compute some stuff */
_bar = Bar (/* ... */)
}
return _bar!
}
}
where access to the property is meant to be through the bar computed property. You find this in Apple CoreData templates.
In Objective-C when you declare a property #synthesize would create the getter and setters for you automatically since clang 3.2. So, the default #synthesize for a property "foo" would look like this:
#synthesize foo = _foo
because of that _foo would then be the iVar. In other words you could have done the #synthesize yourself and called the iVar whatever you liked:
#synthesize foo = myiVarFoo
so in this case there is no "_"
So now in Swift from the documentation:
Swift unifies these concepts into a single property declaration. A Swift property does not have a corresponding instance variable, and the backing store for a property is not accessed directly.
So from the documentation it's clear that swift does not have a corresponding instance variable thus no need to have the "_" around anymore.
The underscore prefix was meant not to confuse the instance variable _foo with its getter foo.
In swift there's not such distinction between ivars and getters. Instead you only have properties, making the _ convention non necessary.
The answer is no because there are no "instance variables" right now in Swift. Only properties (stored properties and computed properties).
I'd say this _underscoreName convention is dropped (although some Apple templates still have it).
Swift's "Lazy Stored Properties" make _these unnecessary. This post:
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
explains it well.
I use a leading underscore to denote a private symbol.
Yes, the underscores do hamper readability at first, but there is a valuable payoff in comprehension and maintainability.
e.g.:
final class SomeClass
{
fileprivate let _kMagicNumber: CGFloat = 3.14
fileprivate struct _PrivateInfo
{
let foo: Int
let bar: String
}
fileprivate var _privateInfo: _PrivateInfo
fileprivate func _setup(with info: _PrivateInfo) { ... }
}
etc.
At a glance, you can see which elements belong where.
You don't need to option-click or do the "who does this belong to?" dance.
Code comprehension shouldn't rely on an IDE's features. And there are times (GitHub, raw text files) where an IDE isn't available.
I understand the "it's not convention" argument. But conventions aren't written on stone tablets. Swift is rapidly evolving, as is our usage of it.
If the Swift team were to produce an annotation syntax for private symbols tomorrow, I'd use it. But until then...
Since I've got my soapbox out, please prefix your extensions.
Consider this snippet:
let color = "#ff7733".hexColor
Where does the "hexColor" come from? Your own code? The Swift standard library? Foundation? UKit? (Hah!) A CocoaPod? Who knows?
(Seasoned CocoaPods users will know that every second open-source library implements a "hexColor" property. With all the problems that entails.)
So, given a company or project name like "Double Secret Probation", consider using:
let color = "#ff7733".dsp_hexColor
Finally, I strongly recommend the books "Writing Solid Code" and "Code Complete".
The convention of a prefixing private vars long preceeded that of ObjCs (weird) property synthesis concept. Clarity was the original reason for such a prefix, not differentiation though it was useful and common to expose a public getter without the underscore...for obvious reasons. IMO, ObjC prop synthesis just put a big fat monkey wrench in the works confusing the h*** out of everyone...
What if you wanted a private synthesized property? In order to underscore-prefix your private synthesized property, you'd need a double underscore backing var. Apple specifically warned against double underscores and this created confusion. Should we bother to use synth'ed properties internally or stick with the backing var (which still had an underscore and was clearly private)? Should we just stop differentiating between private and public vars? Why??
In practice people would use the synthesized version internal to a class as a kind of smart setter, if and only if they wanted the smarts – but that broke down the ideal of encapsulation – choosing whether to use the synth'ed setter required apriori knowledge of what happened behind the scenes.
Meanwhile, as pointed out above, apple's internal code still used the convention, sometimes for synthesized properties too IIRC. And they still do for swift properties! But not consistently...The biggest evidence your language design policy is confusing is when your own devs aren't using it consistently!
Clarity was the original motive and it worked well. I say:
BRING BACK THE UNDERSCORE!
...for private vars and methods :)
(P.S. Dart even has this as an actual language convention in lieu of a private keyword!)

How to share a Dictionary instance in Swift?

According to the Swift Programming Language reference, Dictionary instances are copied whenever they are passed to a function/method or assigned to a constant or variable. This seems inefficient. Is there a way to efficiently share the contents of a dictionary between two methods without copying?
It's true the documentation says that but there are also various notes saying it won't affect the performance. The copying will be performed lazily - only when needed.
The descriptions below refer to the “copying” of arrays, dictionaries, strings, and other values. Where copying is mentioned, the behavior you see in your code will always be as if a copy took place. However, Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization.
Source: Classes & Collections
Meaning - don't try to optimize before you actually encounter performance problems!
Also, don't forget that dictionaries are structures. When you pass them into a function, they are implicitly immutable, so no need for copying. To actually pass a mutable dictionary into a function, you can use an inout parameter and the dictionary won't be copied (passed by reference). The only case when a mutable dictionary passed as a parameter will be copied is when you declare the parameter as var.
You always have the option to define a custom, generic class with a Dictionary attribute:
class SharedDictionary<K, V> {
var dict : Dictionary<K, V>
// add the methods you need, including overloading operators
}
Instances of your SharedDictionary will be passed-by-reference (not copied).
I actually talked to someone on the Swift team today about "pass by reference" in Swift. Here is what I got:
As we all know, struct are pass by copy, classes are pass by
reference
I quote "It is extremely easy to wrap a struct in a class.
Pointing to GoZoner's answer.
Even though though a struct is copied, any classes defined in
the struct will still be passed by reference.
If you want to do traditional pass by reference on a struct, use
inout. However he specifically mentioned to "consider adding in
another return value instead of using inout" when saying this.
Since Dictionary defines KeyType and ValueType as generics:
struct Dictionary<KeyType : Hashable, ValueType>
I believe this means that if your KeyType and ValueType are class objects they will not be copied when the Dictionary itself is copied, and you shouldn't need to worry about it too much.
Also, the NSDictionary class is still available to use!
As other said "Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so." so performance should not be a big problem here. However you might still want to have a dictionary passed by reference for some other reasons. In that case you can create a custom class like below and use it just like you would use a normal dictionary object:
class SharedDictionary<K : Hashable, V> {
var dict : Dictionary<K, V> = Dictionary()
subscript(key : K) -> V? {
get {
return dict[key]
}
set(newValue) {
dict[key] = newValue
}
}
}
Trust the language designers: the compiler is usually smarter than you think in optimizing copies.
You can hack around this, but I don't frankly see a need before proving it's inefficient.