Argument passed to call that takes no arguments.. Firebase - xcode

Not sure why i'm getting this.. any suggestions would be grateful!
I ran into issues with my original coding where I had Firebase pod and Firebase Package.. so I started from scratch since that wasnt fixing itself.. now I get this.. and I am at a loss for how to resolve it.
static func fetchUsers() -> AnyPublisher<[UserProfile], Error> {
Future< [UserProfile], Error > { promise in
self.db.collection("Users")
.getDocuments { (snapshot, error) in
if let error = error {
promise(.failure(error))
return
}
guard let snapshot = snapshot else {
promise(.failure(FirebaseError.badSnapshot))
return
}
var users = [UserProfile]()
snapshot.documents.forEach { document in
print(users.count)
if let user = try? document.data(as: UserProfile.self){
if users.contains(where: { $0.id == user.id}) {return}
users.append(user)
} else {
print("Not working")
}
}
promise(.success(users))
}
}
.eraseToAnyPublisher()
}

I believe this is the syntax you're after:
var users = [UserProfile]()
users = snapshot.documents.compactMap { (document) -> UserProfile? in
if users.contains(where: { $0.id == user.id}) {
return nil
} else {
return try? document.data(as: UserProfile.self)
}
}
Also be aware that when you iterate something in Swift and encounter a false condition on an iteration, return will return out of the greater scope, not just that iteration. Therefore, use continue.
for x in y {
guard x > 0 else {
continue // continues loop
}
// ...
}

Related

What is the meaning of `copyOnWriteContext` in module `github.com/google/btree`?

Recently, I read the source code of google/btree. But I'am conflused by the struct copyOnWriteContext. It is used in node function mutableFor, like following
func (n *node) mutableFor(cow *copyOnWriteContext) *node {
if n.cow == cow {
return n
}
fmt.Println("new node?")
out := cow.newNode()
if cap(out.items) >= len(n.items) {
out.items = out.items[:len(n.items)]
} else {
out.items = make(items, len(n.items), cap(n.items))
}
copy(out.items, n.items)
// Copy children
if cap(out.children) >= len(n.children) {
out.children = out.children[:len(n.children)]
} else {
out.children = make(children, len(n.children), cap(n.children))
}
copy(out.children, n.children)
return out
}
I review all the code in this module, and found that there is only one place create the copyOnWriteContext's instance. It is when the tree is created.
func New(degree int) *BTree {
return NewWithFreeList(degree, NewFreeList(DefaultFreeListSize))
}
So what is the meaning for mutableFor. Because there is only one copyOnWriteContext in the entire code. The n.cow always equals param cow.
n.cow can be nil.
// freeNode frees a node within a given COW context, if it's owned by that
// context. It returns what happened to the node (see freeType const
// documentation).
func (c *copyOnWriteContext) freeNode(n *node) freeType {
if n.cow == c {
// clear to allow GC
n.items.truncate(0)
n.children.truncate(0)
n.cow = nil
if c.freelist.freeNode(n) {
return ftStored
} else {
return ftFreelistFull
}
} else {
return ftNotOwned
}
}

How to Solve NSArray element failed to match the Swift Array Element type in GooglePlaces API findAutocompletePredictions?

I am having trouble analyzing the results given by the callback of GMSPlacesClient findAutocompletePredictionsFromQuery:, which is a GMSAutocompletePrediction array.
The app will crash on let searchResultsWayPoints = finalResults.map ,
stating
Precondition failed: NSArray element failed to match the Swift Array Element type
Expected GMSAutocompletePrediction but found GMSAutocompletePrediction
func getGoogleWayPoint(text: String) -> Promise<[GoogleWayPoint]> {
return Promise<[GoogleWayPoint]> { resolver in
if text.isEmpty {
resolver.fulfill([])
return
}
placesClient.findAutocompletePredictions(fromQuery: text, filter: filter, sessionToken: sessionToken) { (results, error) in
if let error = error {
dprint(error.localizedDescription)
resolver.fulfill([])
return
}
guard let finalResults = results else {
dprint("can't found results")
resolver.fulfill([])
return
}
let searchResultsWayPoints = finalResults.map {
GoogleWayPoint(id: $0.placeID, address: $0.attributedFullText.string)
}
resolver.fulfill(searchResultsWayPoints)
}
}
}
Any help would be appreciated. Thank you.
So I have solved this problem, but I did not fix anything, since it is from the GooglePlaces framework.
In order to solve this, simply make results as results:[Any]? at the callback.
Then, at guard let, safely convert it to [GMSAutocompletePrediction].
Here is the complete code
func getGoogleWayPoint(text: String) -> Promise<[GoogleWayPoint]> {
return Promise<[GoogleWayPoint]> { resolver in
if text.isEmpty {
resolver.fulfill([])
return
}
placesClient.findAutocompletePredictions(fromQuery: text, filter: filter, sessionToken: sessionToken) { (results: [Any]?, error) in
if let error = error {
dprint(error.localizedDescription)
resolver.fulfill([])
return
}
guard let finalResults = results as? [GMSAutocompletePrediction] else {
dprint("can't found results")
resolver.fulfill([])
return
}
let searchResultsWayPoints = finalResults.map {
GoogleWayPoint(id: $0.placeID, address: $0.attributedFullText.string)
}
resolver.fulfill(searchResultsWayPoints)
}
}
}

computed setter for a subscript of an array in Swift [duplicate]

This question already has answers here:
Shorthand setter declaration for a subscript of an array in Swift
(2 answers)
Closed 8 years ago.
To keep it short, what I want to achieve is for example:
var actions: [String]{
get{
if (_actions==nil){
_actions = []
}
return _actions!
}
set{
_actions = newValue
}
subscript(index:Int) -> String{
set {
assert(index<_actions.count && index>=0, "Index out of range")
_actions[index] = newValue
}
}
}
I know subscript isn't an accessor for array, but then what is the most convinient alternative to do just that?
I truly appreciate for succinct answers if possible! Thank you very much!
Edit:
To extend my explanation for #jrturton,
What I am trying to achieve is whenever actions[i] is set to a newValue, I would like to do some extra computations, such as repositioning actions[i]'s respective subview.
But if i say actions[3] = "randomMethod", the computed setter for the entire array will get called. Right? So I'd like to find a way so that when actions[3] is set to a newValue, a function repositionView(3) can get called, for example.
I know other ways to do it, but my question simply askes if there is a more convinient way, like the example above: a computed setter, to do what I want?
Edit 2:
To show #Vatsal Manot what I truly mean, I removed getter for subscript, and here is a complete example.swift(which wont run due to error):
import UIKit
import Foundation
class DWActionsSubmenu: UIView{
var actions: [DWAction]{
get{
if (_actions==nil){
_actions = []
}
return _actions!
}
set{
_actions = newValue
}
subscript(index:Int) -> DWAction{
set {
assert(index<_actions.count && index>=0, "Index out of range")
_actions[index] = newValue
a()
}
}
}
var _actions: [DWAction]?
init(actions:[DWAction]?){
super.init()
_actions = actions
}
required init(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
}
func a(){
}
}
I'd wrap your actions list in a custom class that you can then access via subscripting. You can then add a block to be run whenever a subscripted member is set:
class ActionList {
private var actions = [String]()
var actionDidChange : ((Int) -> ())?
subscript(actionIndex:Int) -> String {
get {
return actions[actionIndex]
}
set {
actions[actionIndex] = newValue
if let actionDidChange = actionDidChange {
actionDidChange(actionIndex)
}
}
}
func addAction(action: String) {
actions.append(action)
}
func addActions(newActions:[String]) {
actions += newActions
}
}
Usage (in a playground):
let actionList = ActionList()
actionList.actionDidChange = {
actionIndex in
println("Action \(actionIndex) did change")
}
actionList.addActions(["One", "Two", "Three"])
actionList[2] = "New"
// Prints "Action 2 did change"
The following should work:
var actions: [String] = []
subscript(index:Int) -> String
{
get
{
assert(index < actions.count && index >= 0, "Index out of range")
return actions[index]
}
set(newValue)
{
assert(index < actions.count && index >= 0, "Index out of range")
actions[index] = newValue
}
}

How to print out value from coredata dictionary in swift 'AnyObject' does not have a member named 'username?

I am trying to print out the value "username" from my coredata entity.
var request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if (results?.count > 0) {
for result: AnyObject in results! {
println(result.username)
}
}
The line println(result.username) is giving me a compile error of 'AnyObject' does not have a member named 'username'.
You have to cast the array of managed object to the correct type:
for result in results! as [Users] {
println(result.username)
}
This assumes that you have created a managed object subclass for the "Users" entity.
You should also distinguish whether executeFetchRequest() returned nil
(i.e. the fetch request failed), or 0 (i.e. no objects found),
and use the error parameter:
var error : NSError?
if let results = context.executeFetchRequest(request, error: &error) {
if (results.count > 0) {
for result in results as [Users] {
println(result.username)
}
} else {
println("No Users")
}
} else {
println("Fetch failed: \(error)")
// Handle error ...
}
Update for Swift 2/Xcode 7 with try/catch error handling:
do {
let results = try context.executeFetchRequest(request) as! [Users]
if (results.count > 0) {
for result in results {
print(result.username)
}
} else {
print("No Users")
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
Note that the forced cast as! [Users] is acceptable here.
The returned objects are always instances of the corresponding class as configured in the Core Data model inspector, otherwise you have
a programming error which should be detected early.
Martin's answer definitely lets you access the properties of your object, but the cast is forced. Like it or not, Swift's strong type system is the future. When returning results from a fetch request, you might consider testing for the type.
func executeFetchRequestT<T:AnyObject>(request:NSFetchRequest, managedObjectContext:NSManagedObjectContext, error: NSErrorPointer = nil) -> [T]? {
var localError: NSError? = nil
if let results:[AnyObject] = managedObjectContext.executeFetchRequest(request, error: &localError) {
if results.count > 0 {
if results[0] is T {
let casted:[T] = results as [T]
return .Some(casted)
}
if error != nil {
error.memory = NSError(domain: "error_domain", code: 0, userInfo: [NSLocalizedDescriptionKey: "Object in fetched results is not the expected type."])
}
} else if 0 == results.count {
return [T]() // just return an empty array
}
}
if error != nil && localError != nil {
error.memory = localError!
}
return .None
}
Using this approach you can type your results and get an error if the type is incorrect.
var fetchError:NSError? = nil
if let results:[Users] = executeFetchRequestT(fetchRequest, managedObjectContext: managedObjectContext, error: &fetchError) {
for user in results {
// access the results with confidence of the correct type
}
} else {
// should have an error condition, handle it appropriately
assertFailure("something bad happened")
}
Change your for loop to this
for result: AnyObject in results! {
if let user: AnyObject = result.valueForKey("username") {
println(user)
}
}
The fix is using valueForKey("String")

Golang if/else not compiling

I cannot figure out why this will not compile.
It says functions ends without a return statement, but when I add a return after the else, it still won't compile.
func (d Foo) primaryOptions() []string{
if(d.Line == 1){
return []string{"me", "my"}
}
else{
return []string{"mee", "myy"}
}
}
Go forces else to be on the same line as the if brace.. because of its "auto-semicolon-insertion" rules.
So it must be this:
if(d.Line == 1) {
return []string{"me", "my"}
} else { // <---------------------- this must be up here
return []string{"mee", "myy"}
}
Otherwise, the compiler inserts a semicolon for you:
if(d.Line == 1) {
return []string{"me", "my"}
}; // <---------------------------the compiler does this automatically if you put it below
else {
return []string{"mee", "myy"}
}
..hence your error. I will link to the relevant documentation shortly.
EDIT: Effective Go has information regarding this.

Resources