Can you upload a custom struct to a Firestore using Swift [closed] - swift

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I am creating an app where I have a custom struct called Piece. This piece has a string name, a string location, and a map/ dict. Is there a way to save this to Firestore?
Example code but this is what I will need to upload.
struct Piece {
name = 2222
location = "Drawer-1"
quantities = ["blue" : 1, "red" : 3]
}
This is my first post ever so sorry if I do things wrong format-wise.

yes - this is possible. I wrote a long blog post about this: Mapping Firestore Data in Swift - The Comprehensive Guide.
In your case, here is how you would do this:
First, make your struct (and the Quantity struct) codable:
struct Piece: Codable {
#DocumentID var id: String?
var name: Int // are you sure that a field containing a number like 2222 should be called "name"?
var location: String
var quantities: [Quantity]
}
struct Quantity: Codable {
var color: String
var amount: Int
}
Then, create a class for accessing Firestore. You can name it PieceStore or PieceRepository, whatever you like.
class PieceStore {
func addPiece(piece: Piece) {
let collectionRef = db.collection("pieces")
do {
let newDocReference = try collectionRef.addDocument(from: piece)
print("Piece stored with new document reference: \(newDocReference)")
}
catch {
print(error)
}
}
}
See the blog post for more details about fetching data using one-time fetches and snapshot listeners (which will give you that cool real-time sync that Firestore is famous for).

Related

How can i import view which bring a closure with itself in SwiftUI? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
Here is my code, it does not work:
struct ContainerView<MyContent: View>: View {
let myContent: () -> MyContent
#State private var myValue: String = ""
var body: some View {
myContent() { value in
myValue = value
}
}
}
I want make this logic works, when I am bringing my view as myContent to body, I want be able to bring a string value with it like in code! I am not looking for reaching my goal with other ways, the goal of this question is be able to access value like in code as clouser.
Warning: I'm not sure what the use-case of this is -- it's not clear what problem is trying to be solved here, but there's likely a better fit that trying to make something like this work. This answer, though, does solve the compilation errors presented above.
Your syntax inside body implies that you want a trailing closure on myContent, but it's not defined in the signature. This would solve the compilation error:
struct ContainerView<MyContent: View>: View {
let myContent: (#escaping (String) -> Void) -> MyContent
#State private var myValue: String = ""
var body: some View {
Text(myValue)
myContent() { value in
myValue = value
}
}
}
Call site:
ContainerView { closure in
Button("Test") {
closure("Value")
}
}

Get the coding key for a keypath in Swift [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
What I have: A codable struct with different properties.
What I want: A function, where I can get the exact name of the property when it is encoded in a Json. I think the most promising approach is using Keypath, but I have no idea how and whether it is possible at all. Thanks!
There is no way to do this out of the box, since there's no 1-1 mapping between properties of a Codable type and its coding keys, since there might be properties that aren't part of the encoded model or properties that depend on several encoded keys.
However, you should be able to achieve your goals by defining a mapping between the properties and their coding keys. You were on the right track with KeyPaths, you just need to define a function that takes a KeyPath whose root type is your codable model and return the coding key from said function.
struct MyCodable: Codable {
let id: Int
let name: String
// This property isn't part of the JSON
var description: String {
"\(id) \(name)"
}
enum CodingKeys: String, CodingKey {
case name = "Name"
case id = "identifier"
}
static func codingKey<Value>(for keyPath: KeyPath<MyCodable, Value>) -> String? {
let codingKey: CodingKeys
switch keyPath {
case \MyCodable.id:
codingKey = .id
case \MyCodable.name:
codingKey = .name
default: // handle properties that aren't encoded
return nil
}
return codingKey.rawValue
}
}
MyCodable.codingKey(for: \.id)

How to use a protocol inside a function in Swift? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm going through a series of Swift tutorials and I don't want to move forward without understanding the point of this
protocol Identifiable {
var id: String { get set }
}
/*:
We can’t create instances of that protocol - it’s a description, not a type by itself.
But we can create a struct that conforms to it:
*/
struct User: Identifiable {
var id: String
}
//: Finally, we’ll write a `displayID()` function that accepts any `Identifiable` object:
func displayID(thing: Identifiable) {
print("My ID is \(thing.id)")
}
This is the tutorial page
Say I want to now run displayID and get the thing.id, how would that work?
You can try it on swift playgrounds this is one way you can use it for example:
import Foundation
protocol Identifiable {
var id: String { get set }
}
struct User: Identifiable {
var id: String
}
class ViewController {
func displayID(thing: Identifiable) {
print("My ID is \(thing.id)")
}
}
let vc = ViewController()
let user = User(id: "12")
vc.displayID(thing: user)
// My ID is 12
Usually protocols are seen like contracts (interfaces in java/android) for a class or struct to follow, so you know that making a class or a struct comforming to a protocol will assure you an implementation of your basic methods that you might require for that kind of object/instance in future.
As well they are meant to allow you to provide in your automated tests for example a mocked sample of the implementation in order to get a mock id instead of a real one as in this example.
A protocol simply means ...
you MUST have all the stuff stated!
That is all a protocol is!
Here's your protocol
protocol Identifiable {
var id: String { get set }
}
all that means is you MUST have a "id" !
So this:
class Test: Identifiable {
}
is wrong !!!
But this:
class Test: Identifiable {
var id: String
}
is correct !!!
That's all it is!
Protocols are that simple!
Yes, it is true you cannot create an instance of protocol. But you can create an instance of classes and struct that implements protocol. Protocol just ensure that the struct or class that implements this protocol must have all these properties and methods that are defined in the protocol. You can say that Protocol is a contract. You need to fulfill it if you implements it.

Swift - Merging 2 arrays of objects with a key [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm new to Swift programming and been working on an app fir a couple of weeks now, and I'm stuck at a crucial moment in the development.
I'm fetching data from a URL that returns a JSON. It is decoded and the data o is stored in an array.
I do the same thing with another URL.
Now I'm trying to initialize my final object wich will be a combination of 2 objects contained in each of the arrays.
Each array is a dictionary and each objects has a property call id.
I can't figure how I can go through each arrays to check for the id of each objects to match and then initialize a new object by combining the data from each object (look at the code below, it will make more sense hopefully)
I tried a for ... in but I couldn't access the id property and compare it. I tried to do a for ... in inside a for ... in to compare the id value: no success too.
On top of this, the initialization is also a challenge. I tried to implement something like this:
self.mergedList = (//result of the loops).map(MergedViewModel.init)
Here an example of the 2 objects
class MergeInformationViewModel {
var id = "1234"
var information = "This Is My Name"
}
class MergeDataViewModel {
var id = "1234"
var data = "Some very important data"
}
The object I'm trying to initialize
class MergedViewModel {
let mergedViewData: MergeDataViewModel
let mergedViewInformation: MergeInformationViewModel
init(data: MergeDataViewModel, information: MergeInformationViewModel) {
self.mergedViewData = data
self.mergedViewInformation = information
}
var id: String {
return self.mergedViewData.id
}
var information: String {
return self.mergedViewInformation.information
}
var data: String {
return self.mergedViewData.data
}
}
Finally the class handling the initialization. I'm working on a SwiftUI project
class MergedListViewModel: ObservableObject {
init() { mergingAndInit() }
#Published var mergedList = [MergedViewModel]()
var mergeInformationList = [MergeInformationViewModel]()
var mergeDataList = [MergeDataViewModel]()
func mergingAndInit() {
//...
}
}
the final result would look something like this
class MergedViewModel {
var id = "1234"
var information = "This Is My Name"
var data = "Some very important data"
}
How can I implement the func mergingAndInit() into my code?
Thanks in advance.
I figure it out!
for mergedI in mergeInformationList {
for mergedD in mergeDataList {
if mergedI.id == mergedD.id {
self.mergedList.append(MergedViewModel(data: mergedD, information: mergedI))
}
}
}

Value type of string? Has no member components. (Struct) [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I look at each thread but can't find any solution for my case.
I have a model:
import Foundation
public struct Destinos: Data {
public var idDestino : Int?
public var desDestino : String?
public func dictionary() -> NSDictionary {
let dictionary = NSMutableDictionary()
dictionary.setValue(self.idDestino, forKey: "idDestino")
dictionary.setValue(self.desDestino, forKey: "desDestino")
return dictionary
}
}
So I want to change the desDestino "string" to [String] to use later and show in at tableView. For this.I write this line of code in another file.swift:
var cadena = Destinos()
cadena.desDestino = "HOLA, nada, algo, otra, cosa, mas que eso"
let array = cadena.desDestino.components(separatedBy: ", ") // in this line i get the error: value type of string? has no member components.
so... what is the problem?
There's no reason to use NSDictionary here. Just use a native Swift dictionary (with a literal).
public struct Destinos {
public let idDestino : Int?
public let desDestino : String?
public func toDictionary() -> [String: Any?] {
return [
"idDestino": idDestino,
"desDestino": desDestino
]
}
}
As for generating your array, you have two issues:
1. components(seperatedBy:) is misspelt
2. cadena.desDestino is an is a String? (Also known as a Optional<String>) which hasn't been unwrapped. The nicest way to take care of this is to use optional chaining, and then use nil coalescence (??) to make it an empty array in the case cadena.desDestino is nil.
var cadena = Destinos(
idDestino: 123,
desDestino: "HOLA, nada, algo, otra, cosa, mas que eso"
)
let array = cadena.desDestino?.components(separatedBy: ", ") ?? []