I was wondering if I could ask a question regarding csv/http posting. I want my data to update within my app after I pull the data from my github csv file, but when I do, it doesn't update within the app but just prints the numbers. What's wrong with my code? Thanks!
class NewStats: UITableViewController {
var didTapMenuType: ((NewMenu) -> Void)?
var Num2:String = "2"
#IBOutlet weak var MultnomahText: UILabel!
#IBOutlet weak var MultnomahView: UIProgressView!
override func viewDidLoad() {
let url = URL(string: "SampleUrl.csv")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
let str = (String(data: data, encoding: .utf8)!)
let fullNameArr = str.components(separatedBy: ",")
let Num1 = fullNameArr[0]
self.Num2 = fullNameArr[1]
let Num3 = fullNameArr[2]
let Num4 = fullNameArr[3]
let Num5 = fullNameArr[4]
let Num6 = fullNameArr[5]
let Num7 = fullNameArr[6]
let Num8 = fullNameArr[7]
let Num9 = fullNameArr[8]
let Num10 = fullNameArr[9]
print(Num1);
print(self.Num2);
print(Num3);
print(Num4);
print(Num5);
print(Num6);
print(Num7);
print(Num8);
print(Num9);
print(Num10);
}
task.resume()
super.viewDidLoad()
DispatchQueue.main.async {
self.tableView.reloadData()
}
print(self.Num2);
self.MultnomahText.text = "Multnomah:" + self.Num2
self.MultnomahView.setProgress(0.5, animated: true)
}
After the print(Num10)
DispatchQueue.main.async {
self.MultnomahText.text = "Multnomah:" + self.Num2
self.MultnomahView.setProgress(0.5, animated: true)
self.tableView.reloadData()
}
Hopefully this helps!
Related
I am using this line below :
self.present(activityViewController, animated: true, completion: nil)
And I am getting an error of - Use of unresolved identifier 'self'. Any ideas about how to resolve this? To me it looks as it it is subordinate to the class, but clearly doing something wrong. Any help would be appreciated.
import UIKit
import CoreData
class CoreDataViewController: UIViewController {
#IBOutlet weak var CoreDataView: UITableView!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var items:[Checkins]?
var btnnames = [""]
override func viewDidLoad() {
super.viewDidLoad()
// CoreDataView.dataSource = self
// CoreDataView.delegate = self
storeTranscription()
// Loads the current data
getTranscriptions()
// fetchCheckins()
let btn1name = btnnames[0]
let btn2name = btnnames[1]
let btn3name = btnnames[2]
let btn4name = btnnames[3]
let btn5name = btnnames[4]
let btn6name = btnnames[5]
// print(btnnames)
print(btn1name, btn2name, btn3name, btn4name, btn5name, btn6name)
}
#IBAction func export(_ sender: Any) {
exportDatabase()
}
#IBOutlet weak var Table_label: UILabel!
}
var CheckinDate: Date? = Date()
var fetchedStatsArray: [NSManagedObject] = []
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func storeTranscription() {
//retrieve the entity that we just created
let entity = NSEntityDescription.entity(forEntityName: "Checkins", in: context)
let transc = NSManagedObject(entity: entity!, insertInto: context) as! Checkins
//set the entity values
transc.who = "Who"
transc.reason = "Reason for visit"
transc.date = CheckinDate
//save the object
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
func getTranscriptions () {
//create a fetch request, telling it about the entity
let fetchRequest: NSFetchRequest<Checkins> = Checkins.fetchRequest()
do {
//go get the results
let searchResults = try context.fetch(fetchRequest)
fetchedStatsArray = searchResults as [NSManagedObject]
//I like to check the size of the returned results!
print ("num of results = \(searchResults.count)")
//You need to convert to NSManagedObject to use 'for' loops
for trans in searchResults as [NSManagedObject] {
//get the Key Value pairs (although there may be a better way to do that...
print("\(trans.value(forKey: "who")!)")
let mdate = trans.value(forKey: "CheckinDate") as! Date
print(mdate)
}
} catch {
print("Error with request: \(error)")
}
}
func exportDatabase() {
let exportString = createExportString()
saveAndExport(exportString: exportString)
}
func saveAndExport(exportString: String) {
let exportFilePath = NSTemporaryDirectory() + "Checkins.csv"
let exportFileURL = NSURL(fileURLWithPath: exportFilePath)
FileManager.default.createFile(atPath: exportFilePath, contents: NSData() as Data, attributes: nil)
//var fileHandleError: NSError? = nil
var fileHandle: FileHandle? = nil
do {
fileHandle = try FileHandle(forWritingTo: exportFileURL as URL)
} catch {
print("Error with fileHandle")
}
if fileHandle != nil {
fileHandle!.seekToEndOfFile()
let csvData = exportString.data(using: String.Encoding.utf8, allowLossyConversion: false)
fileHandle!.write(csvData!)
fileHandle!.closeFile()
let firstActivityItem = NSURL(fileURLWithPath: exportFilePath)
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [firstActivityItem], applicationActivities: nil)
activityViewController.excludedActivityTypes = [
UIActivity.ActivityType.assignToContact,
UIActivity.ActivityType.saveToCameraRoll,
UIActivity.ActivityType.postToFlickr,
UIActivity.ActivityType.postToVimeo,
UIActivity.ActivityType.postToTencentWeibo
]
self.present(activityViewController, animated: true, completion: nil)
}
}
func createExportString() -> String {
var checkinwho: String?
var checkinreason: String?
var export: String = NSLocalizedString("who, reason, date \n", comment: "")
for (index, itemList) in fetchedStatsArray.enumerated() {
if index <= fetchedStatsArray.count - 1 {
checkinwho = Checkins.value(forKey: "who") as! String?
checkinreason = itemList.value(forKey: "reason") as! String?
let Datevar = Checkins.value(forKey: "date") as! Date
let whostring = checkinwho
let reasonstring = checkinreason
let DateSting = "\(Datevar)"
export += "\(whostring!),\(reasonstring!),\(DateSting) \n"
}
}
print("This is what the app will export: \(export)")
return export
}
Remove the } on this line
#IBOutlet weak var Table_label: UILabel!
}
and put another } at the end of this file.
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'm trying to capture a user input (textfield + button) and reuse the result later in the program but I don't know how to do that.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var resultLabel: UILabel!
#IBOutlet weak var moneyTextField: UITextField!
#IBAction func convert(_ sender: Any) {
let convertion:Double = Double(moneyTextField.text!)!
print(convertion)
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://www.x-rates.com/calculator/?from=EUR&to=USD&amount=1")!
let request = NSMutableURLRequest(url : url)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
var rateValue:Double = 0.0;
if let error = error {
print(error)
} else {
if let unwrappedData = data {
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
var stringSeperator = "<span class=\"ccOutputRslt\">"
if let contentArray = dataString?.components(separatedBy: stringSeperator){
if contentArray.count > 0 {
stringSeperator = "<span"
let newContentArray = contentArray[1].components(separatedBy: stringSeperator)
if newContentArray.count > 0 {
rateValue = Double(newContentArray[0])!
print(newContentArray[0])
}
}
}
}
}
//
print("Rate is \(rateValue)");
DispatchQueue.main.sync(execute: {
self.resultLabel.text = "the value of the dollar is " + String(rateValue)
}
)}
task.resume()
}
}
What I want to do is take the let convertion and multiply it by rateValue at the end of the code. I tried different thing but without any results.
after the advice from Joakim Danielson
I did that :
import UIKit
class ViewController: UIViewController {
var fxRate: Double?
#IBOutlet weak var resultLabel: UILabel!
#IBOutlet weak var moneyTextField: UITextField!
#IBAction func convert(_ sender: Any) {
let convertion:Double = Double(moneyTextField.text!)!
print(convertion)
var convertedAmount = 0.0
if let rate = fxRate, let money = Double(moneyTextField.text) {
convertedAmount = rate * money
}
print(convertedAmount)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let url = URL(string: "https://www.x-rates.com/calculator/?from=EUR&to=USD&amount=1")!
let request = NSMutableURLRequest(url : url)
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
var rateValue:Double = 0.0;
if let error = error {
print(error)
} else {
if let unwrappedData = data {
let dataString = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)
var stringSeperator = "<span class=\"ccOutputRslt\">"
if let contentArray = dataString?.components(separatedBy: stringSeperator){
if contentArray.count > 0 {
stringSeperator = "<span"
let newContentArray = contentArray[1].components(separatedBy: stringSeperator)
if newContentArray.count > 0 {
rateValue = Double(newContentArray[0])!
print(newContentArray[0])
rateValue = Double(newContentArray[0])!
self.fxRate = rateValue
}
}
}
}
}
//
print("Rate is \(rateValue)");
DispatchQueue.main.sync(execute: {
self.resultLabel.text = "the value of the dollar is " + String(rateValue)
}
)}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
but I have the error : Cannot invoke initializer for type 'Double' with an argument list of type '(String?)' on line 26. Can you please help me? thx!
create a variable outside of your function
var anyVariableYouWantToAccessLater: Double?
And use this variable anywhere you want.
Since you're downloading the rate during viewDidLoad I am assuming this is what you want to keep.
Add a new property to the class
class ViewController: UIViewController {
var fxRate: Double?
...
In viewDidLoad update this property with the downloaded value
rateValue = Double(newContentArray[0])!
fxRate = rateValue
In the convert func (or wherever you want to use the rate)
#IBAction func convert(_ sender: Any) {
var convertedAmount = 0.0
if let rate = fxRate, let money = Double(moneyTextField.text ?? "0") {
convertedAmount = rate * money
}
print(convertedAmount)
}
When I try to press on any button on my calculator it gives me the error unrecognized selector sent to instance 0x7f7f85e04e40 I updated this code from Swift 2 to Swift 4 but back then it used to work. What's wrong with the code?
import UIKit
class Valuta: UIViewController {
#IBOutlet weak var euro: UILabel!
#IBOutlet weak var zloty: UILabel!
#IBOutlet weak var topButton: UIButton!
#IBOutlet weak var bottomButton: UIButton!
var valutas : [ValutaWaarde] = []
var number = 0;
var isTypingNumber = false
var currentNumber = 0;
var currency = "PLN";
#IBAction func numberTapped(sender: AnyObject) {
let number = sender.currentTitle!
var disable = false
if number == "."{
if euro.text!.range(of: ".") != nil{
disable = true
}
}
if(disable == false){
if isTypingNumber {
euro.text = euro.text!+number!
} else {
euro.text = number
isTypingNumber = true
}
var output : Float;
if(currency == "EUR"){
output = (euro.text! as NSString).floatValue*Float((valutas[0].rates?.pLN!)!)
}
else{
output = (euro.text! as NSString).floatValue/Float((valutas[0].rates?.pLN!)!)
}
zloty.text = String(format: "%.2f", output)
}
}
#IBAction func resetCalculator(sender: AnyObject) {
isTypingNumber = false;
zloty.text = "0";
euro.text = "0";
}
override func viewDidLoad() {
super.viewDidLoad()
UINavigationBar.appearance().isTranslucent = false;
UINavigationBar.appearance().barTintColor = UIColor(red: CGFloat(51/255.0), green: 51/255, blue: 51/255, alpha: 1)
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
//Get list
let url = URL(string: "https://api.fixer.io/latest?symbols=PLN&base=EUR")
var request = NSMutableURLRequest(url: url! as URL, cachePolicy: NSURLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: Double.infinity)
if Reachability.isConnectedToNetwork(){
request = NSMutableURLRequest(url: url! as URL, cachePolicy: NSURLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: Double.infinity);
}
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest,
completionHandler: { data, response, error -> Void in
do {
if let json = try JSONSerialization.jsonObject(with: data!) as? [[String: String]] {
for valutaData in json {
let valuta = ValutaWaarde(dictionary: valutaData as NSDictionary)
self.valutas.append(valuta!)
}
}
} catch { print(error) }
})
task.resume()
}
...
}
Try to re-connect #IBOutlets and #IBActions in storyboard.
My code calls Firebase and gets user information and user images. Once that's loaded, the app populates an image field and a text label. At least, that's what's supposed to happen. But instead, I'm getting fatal error: Index out of range error. What am I missing?
Here's my code:
#IBOutlet weak var userImage: UIImageView!
#IBOutlet weak var instructionsLabel: UILabel!
var currentUserName: String!
func loadExistingUsers(completion: #escaping () -> ()) {
ref.child("members").observe(.childAdded) { (snapshot: FIRDataSnapshot) in
if let dict = snapshot.value as? [String : Any] {
let userPhotoUrl = dict["profileImageUrl"] as! String
let userFirstName = dict["firstName"] as! String
let userBirthday = dict["birthday"] as! Int
let userPasscode = dict["passcode"] as! Int
let userGender = dict["gender"] as! String
let isUserChildOrParent = dict["childParent"] as! String
let storageRef = FIRStorage.storage().reference(forURL: userPhotoUrl)
storageRef.data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
let pic = UIImage(data: data!)
let user = User(profilePhoto: pic!,
userFirstName: userFirstName,
userBirthday: userBirthday,
userPasscode: userPasscode,
userGender: userGender,
isUserChildOrParent: isUserChildOrParent)
self.users.append(user)
self.users.sort(by: {$0.birthday < $1.birthday})
})
completion()
}
}
}
and my ViewDidLoad call:
loadExistingUsers {
self.currentUserName = self.users[0].firstName // error here
self.instructionsLabel.text = "Choose daily and weekly job assignments for \(self.users[0].firstName)."
self.userImage.image = self.users[0].photo
}
What am I doing wrong? I know my base code is good because I've tested it. Is it just the completion handler that's the problem? Any help would be greatly appreciated.