cannot use instance member 'ref' with the initializer error - swift

I am facing this error all is well, I want to print the children of "12356" in console but i am getting this error i dont know why this is happening and here is the Firebase structure
and this is the xcode error
and here is the code
import UIKit
import Firebase
import FirebaseDatabase
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
var ref = FIRDatabase.database().reference()
let root = ref.child("Items").child("Flate").child("12356")
root.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() { return }
//print(snapshot)
if let myfRateA = snapshot.value["fRateA"] as? String {
print(myfRateA)
}
if let myfRateB = snapshot.value["fRateB"] as? String {
print(myfRateB)
}
})
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

You did not put your code into the right place, because it is outside any method or function. Put it inside a function's body like so:
func printChildren(){
let ref = FIRDatabase.database().reference()
let root = ref.child("Items").child("Flate").child("12356")
root.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() { return }
//print(snapshot)
let myfRateA = (snapshot.value as? NSDictionary)?["fRateA"] as? String ?? ""
print(myfRateA)
let myfRateB = (snapshot.value as? NSDictionary)?["fRateB"] as? String ?? ""
print(myfRateB)
})
}
And call it in viewDidLoad() like so:
override func viewDidLoad() {
super.viewDidLoad()
self.printChildren()
}

Related

Deleting a binary data image by a instance

In my Swift code below the goal is to delete a binary data by the corresponding var Int. The var Int is called counterImage. My code right now is causing a runtime error of counterImage
'Cannot convert value of type 'Int' to expected argument type 'TheBook''
What can I do to fix this? All the code is right here. You would have to add the images but after that you can just copy and paste the code.
import UIKit;import CoreData
class ViewController: UIViewController {
var counterImage = 1
override func viewDidLoad() {
super.viewDidLoad()
let gwen = UIImage(named: "h")
if let imageData = gwen.self?.pngData() {
helpImage.shareInstance.saveImage(data: imageData)
}
let gwen2 = UIImage(named: "hh")
if let imageData = gwen2.self?.pngData() {
helpImage.shareInstance.saveImage(data: imageData)
}
helpImage.shareInstance.deleteObject(user: counterImage)
}
}
class helpImage: UIViewController{
private class func getContext() -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
static let shareInstance = helpImage()
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func saveImage(data: Data) {
let imageInstance = TheBook(context: context)
imageInstance.pic = data
do {
try context.save()
} catch {
print(error.localizedDescription)
}
}
func deleteObject(user: TheBook) {
let context = helpImage.getContext()
let delete = NSBatchDeleteRequest(fetchRequest: TheBook.fetchRequest())
do {
try context.execute(delete)
} catch {
}
}
}

Variable is not updating - func takes default variable

In my ThirdScreenViewController I change the variable number with the IBAction pressed.
import Foundation
import UIKit
class ThirdScreenViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
var weatherManager = WeatherManager()
var team = "leer"
static var number = 1
#IBAction func bayernMunchen(_ sender: UIButton) {
team = "bayernMunchen"
}
#IBAction func borussiaDortmund(_ sender: UIButton) {
team = "borussiaDortmund"
}
#IBAction func schalke(_ sender: UIButton) {
team = "schalke"
}
#IBAction func pressed(_ sender: UIButton) {
switch team {
case "bayernMunchen":
ThirdScreenViewController.number = 46
case "borussiaDortmund":
ThirdScreenViewController.number = 41
case "schalke":
ThirdScreenViewController.number = 45
default: print(8)
}
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "WeatherViewController") as! WeatherViewController
self.present(nextViewController, animated:true, completion:nil)
}
}
In an other swift (not a View Controller) file I have a function which takes number and does something with it.
import Foundation
import UIKit
var TeamOne = ""
var TeamTwo = ""
var ScoreOne = ""
var ScoreTwo = ""
var TeamThree = ""
var TeamFour = ""
var ScoreThree = ""
var ScoreFour = ""
var cityName = ThirdScreenViewController.number
struct WeatherManager {
let weatherURL = "https://livescore-api.com/api-client/teams/matches.json?number=10&team_id=19&key=d33FTnnd6qwvEmjz&secret=BbO3REPYFXvb7fpkit0cQnpXNWssiL1U&number=3&team_id=\(cityName)"
func fetchWeather () {
let urlString = "\(weatherURL)"
perfromRequest(urlString: urlString)
}
func perfromRequest(urlString: String)
{
//1.Url erstellen
if let url = URL(string: urlString) {
//2. URLSession starten
let session = URLSession(configuration: .default)
//3. Give session a task
let task = session.dataTask(with: url) { (gettingInfo, response, error) in
if error != nil{
print(error!)
return
}
if let safeFile = gettingInfo {
self.parseJSON(weatherFile: safeFile)
}
}
//4. Start the task
task.resume()
}
}
//Das Ergebnis von oben wird hier ausgegeben
func parseJSON(weatherFile: Data) {
let decoder = JSONDecoder()
do{
let decodedFile = try decoder.decode(WeatherFile.self, from: weatherFile)
TeamOne = decodedFile.data[0].home_name
ScoreOne = decodedFile.data[0].score
TeamTwo = decodedFile.data[0].away_name
ScoreTwo = decodedFile.data[0].score
TeamThree = decodedFile.data[1].home_name
ScoreThree = decodedFile.data[1].score
TeamFour = decodedFile.data[1].away_name
ScoreFour = decodedFile.data[1].score
} catch {
print(error)
}
}
}
In a third swift file I use this func weatherManager.fetchWeather() to call what happens in my second swift file.
But here is the problem. It takes the variable number with the default value 1 and not with the value 41/46/45. What am I doing wrong?
Basically global variables outside of any class and static variables to share data is bad practice.
Apart from that to get the team ID dynamically delete the line
var cityName = ThirdScreenViewController.number
In the struct replace
let weatherURL = "https://livescore-api.com/api-client/teams/matches.json?number=10&team_id=19&key=d33FTnnd6qwvEmjz&secret=BbO3REPYFXvb7fpkit0cQnpXNWssiL1U&number=3&team_id=\(cityName)"
with
let weatherURL = "https://livescore-api.com/api-client/teams/matches.json?number=10&team_id=19&key=d33FTnnd6qwvEmjz&secret=BbO3REPYFXvb7fpkit0cQnpXNWssiL1U&number=3&team_id="
and
let urlString = "\(weatherURL)"
with
let urlString = weatherURL + String(ThirdScreenViewController.number)
Note: Consider to rename the weather related stuff to the team related stuff

I can not solve it. Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Premise
I am currently making SNS with Swift.
I encountered the following error message while implementing user added functionality on it.
Error message
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Code
Swift4
import UIKit
class PeopleViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var users = [UserModel]()
var userUid = ""
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.tableFooterView = UIView(frame: .zero)
tableView.rowHeight = 80
loadUser()
}
func loadUser() {
UserApi.shared.observeUser { (user) in
self.isFollowing(userUid: user.uid!, completed: { (value) in
**if user.uid != UserApi.shared.CURRENT_USER_UID! {** <-errorPoint
user.isFollowing = value
self.users.append(user)
self.tableView.reloadData()
}
})
}
}
func isFollowing(userUid: String, completed: #escaping (Bool) -> Void ) {
FollowApi.shared.isFollowing(withUser: userUid, completed: completed)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowUserInfoSegue" {
let showUserInfoVC = segue.destination as! ShowUserinfoViewController
showUserInfoVC.userUid = self.userUid
}
}
}
extension PeopleViewController: PeopleCellDelegate {
func didTappedShowUserInfo(userUid: String) {
self.userUid = userUid
performSegue(withIdentifier: "ShowUserInfoSegue", sender: self)
}
}
extension PeopleViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PeopleTableViewCell", for: indexPath) as! PeopleTableViewCell
cell.user = users[indexPath.row]
cell.delegate = self
return cell
}
}
Code
Swift4
import Foundation
import FirebaseDatabase
import FirebaseAuth
class UserApi {
var REF_USERS = Database.database().reference().child("users")
static var shared: UserApi = UserApi()
private init() {
}
var CURRENT_USER_UID: String? {
if let currentUserUid = Auth.auth().currentUser?.uid {
return currentUserUid
}
return nil
}
var CURRENT_USER: User? {
if let currentUserUid = Auth.auth().currentUser {
return currentUserUid
}
return nil
}
func observeUser(uid: String, completion: #escaping (UserModel) -> Void) {
REF_USERS.child(uid).observeSingleEvent(of: .value) { (snapshot) in
guard let dic = snapshot.value as? [String: Any] else { return }
let newUser = UserModel(dictionary: dic)
completion(newUser)
}
}
func observeUser(completion: #escaping (UserModel) -> Void ) {
REF_USERS.observe(.childAdded) { (snapshot) in
guard let dic = snapshot.value as? [String: Any] else { return }
let user = UserModel(dictionary: dic)
completion(user)
}
}
func observeCurrentUser(completion: #escaping (UserModel) -> Void ) {
guard let currentUserUid = CURRENT_USER_UID else { return }
REF_USERS.child(currentUserUid).observeSingleEvent(of: .value) { (snapshot) in
guard let dic = snapshot.value as? [String: Any] else { return }
let currentUser = UserModel(dictionary: dic)
completion(currentUser)
}
}
func queryUser(withText text: String, completion: #escaping(UserModel) -> Void ) {
REF_USERS.queryOrdered(byChild: "username_lowercase").queryStarting(atValue: text).queryEnding(atValue: text + "\u{f8ff}").queryLimited(toLast: 5).observeSingleEvent(of: .value) { (snapshot) in
snapshot.children.forEach({ (data) in
let child = data as! DataSnapshot
guard let dic = child.value as? [String: Any] else { return }
let user = UserModel(dictionary: dic)
completion(user)
})
}
}
}
What I tried
How can I fix "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" in Swift
https://learnappmaking.com/found-nil-while-unwrapping-optional-value/
I browsed and examined these sites, but it did not work.
I think that user information can not be taken out successfully.
Supplementary information
We will add additional information if we have other missing information.
Since I often do not understand Swift in 3 weeks, I would like you to tell me with concrete code etc.
Also, I am happy if you can tell me the cause of the error.
FW / tool version
You're trying to access the CURRENT_USER_UID from UserApi Singleton class which is Optional computed property which seems to be returning nil.
If there's not current user signed-in than Firebase Auth returns nil instead of uid
Auth.auth().currentUser?.uid // Because of Optional Chaining
I'd Suggest you to safely unwrap Optionals.
func loadUser() {
UserApi.shared.observeUser { (user) in
self.isFollowing(userUid: user.uid!, completed: { (value) in
if let currentUser = UserApi.shared.CURRENT_USER_UID {
if user.uid != currentUser {
user.isFollowing = value
self.users.append(user)
self.tableView.reloadData()
}
} else {
// Current user not Signed-In
}
})
}
}

Swift service class to retrieve Firebase data

I have a service class to fetch data from my Firebase:
class Service {
var myName = String?
var myDev: String?
func getData() {
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("Data").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let name = value?["name"] as? String ?? ""
self.myName = name
let dev = value?["dev"] as? String ?? ""
self.myDev = dev
}) { (error) in
print(error.localizedDescription)
}
}
}
and realization in my Main class:
var service = Service()
override func viewDidLoad(){
super.viewDidLoad()
service.getData()
configureLabel()
}
private func configureLabel(){
self.titleLabel.text = service.myName
self.devLabel.text = service.myDev
}
The problem is: data from Firebase fetched only after my label got values of myName and myDev.Thus, this values is nil.
this is not the best solution, but it should solve your problem.
struct MyStructure {
var name = ""
var dev = ""
init(with dictionary: [String: String]) {
if let name = dictionary["name"] {
self.name = name
}
if let dev = dictionary["dev"] {
self.dev = dev
}
}
}
class Service {
let databaseRef = FIRDatabase.database().reference()
func getData(completion: #escaping ((_ structure: MyStructure) -> Void)) {
databaseRef.child("Data").observeSingleEvent(of: .value, with: { snapshot in
if let value = snapshot.value as? [String: String] {
completion(MyStructure(with: value))
}
}) { (error) in
print(error.localizedDescription)
}
}
}
let service = Service()
override func viewDidLoad() {
super.viewDidLoad()
service.getData { myStructure in
DispatchQueue.main.async {
self.titleLabel.text = myStructure.name
self.devLabel.text = myStructure.dev
}
}
}
Of course it does. The getData() method makes an asynchronous call to the Firebase service. Meaning, the .observeSingleEvent method of firebase runs in a async queue as most code blocks that makes a service call. So the compiler reaches to getData() line, pushes the block to a different queue and continues to compile the next lines which are in the original queue. If you want those lines to run after you receive the response, you may add a closure to your getData() method as a parameter.
You can do something like this:
getData(completion: () -> Void) {
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("Data").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let name = value?["name"] as? String ?? ""
self.myName = name
let dev = value?["dev"] as? String ?? ""
self.myDev = dev
completion()
}) { (error) in
print(error.localizedDescription)
}
}
override func viewDidLoad(){
super.viewDidLoad()
service.getData(completion: { Void in
configureLabel()
})
}

swift use class instances to implement variable

My aim is to implement first a viewtable with json data in a view controller.
Then in another viewcontroller i want to choose some record from table to view.
First my class Route is above
class Route {
var id: Int?
var travelTimeSeconds: Int?
var condition:String?
var lastUpdate:String?
var title:String?
var backup = [Route]()
init(json: NSDictionary) {
self.id = json["id"] as? Int
self.travelTimeSeconds = json["travelTimeSeconds"] as? Int
self.condition = json["condition"] as? String
self.lastUpdate = json["lastUpdate"] as? String
self.title = json["title"] as? String
}
init(){}
func findRoutes(predferedroute:String)->[Route] {
let jsonurl = NSURL(string: predferedroute)!
let task = NSURLSession.sharedSession().dataTaskWithURL(jsonurl) { (data,response, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if let urlcontent = data {
do{
let jsonresult = try NSJSONSerialization.JSONObjectWithData(urlcontent, options: NSJSONReadingOptions.MutableContainers)
if let routeArray = jsonresult["result"] as? [NSDictionary] {
for item in routeArray {
self.backup.append(Route(json: item))
}//end for
}//end if
}//end do
catch {
print("Serialization error")
}//end catch
}//end if
})//end dispatch
}//end task
task.resume()
return self.backup
}//end findRoutes
}
in the first view cotroller i write the following code
class MenuPageViewController: UIViewController{
var routes = [Route]()
var implementroutes = Route()
var allroutes:String = "http://quickweb.gr/itsweb/webservices/json?op=GetAll"
var activeRoutes:String = "http://quickweb.gr/itsweb/webservices/json?op=GetActive"
override func viewDidLoad() {
super.viewDidLoad()
NSUserDefaults.standardUserDefaults().setObject("palios55", forKey: "StartUp")
let nickname1 = NSUserDefaults.standardUserDefaults().objectForKey("StartUp")!
print(nickname1)
routes = implementroutes.findRoutes(allroutes)
routes = implementroutes.backup
}//end viewload
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
the other delegates for table view works
but still remain nil the routes for both of two codes:
routes = implementroutes.findRoutes(allroutes)
routes = implementroutes.backup
Does i miss something with viewcontrollers and classes?
if i use the same code directly in tableview it works.