Swift- Pass textfield from swift file to other swift file - ios

I am a newbie
and I try to explain what my problem is:
I have a swift file its name is feedmodel.swift:
import Foundation
protocol FeedmodelProtocol: class {
func itemsDownloaded(items: NSArray)
}
class Feedmodel: NSObject, URLSessionDataDelegate {
weak var delegate: FeedmodelProtocol!
func downloadItems() {
let myUrl = URL(string: "http://example.net/stock_service4.php");
let defaultSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
var request = URLRequest(url:myUrl!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "Latitudee=19.4&Longitudee=-99.1";
request.httpBody = postString.data(using: .utf8)
let task = defaultSession.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
self.parseJSON(data)
}
task.resume()
}
and I have a swift file its name is NeuerBeitragViewController:
import UIKit
import CoreLocation
class NeuerBeitragViewController: UIViewController,CLLocationManagerDelegate {
#IBOutlet weak var Tankstelle: UITextField!
#IBOutlet weak var Kraftstoff1: UITextField!
#IBOutlet weak var Preis1: UITextField!
#IBOutlet weak var Kraftstoff2: UITextField!
#IBOutlet weak var Preis2: UITextField!
#IBOutlet weak var Notiz: UITextField!
#IBOutlet weak var Longitude: UITextField!
#IBOutlet weak var Latitude: UITextField!
var locationManager: CLLocationManager = CLLocationManager()
var startLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
startLocation = nil
}
#IBAction func startWhenInUse(_ sender: Any) {
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
let latestLocation: CLLocation = locations[locations.count - 1]
Latitude.text = String(format: "%.4f",
latestLocation.coordinate.latitude)
Longitude.text = String(format: "%.4f",
latestLocation.coordinate.longitude)
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
print(error.localizedDescription)
}
In my NeuerBeitragViewController.Swift
I have this line:
Latitude.text = String(format: "%.4f",
latestLocation.coordinate.latitude)
Longitude.text = String(format: "%.4f",
latestLocation.coordinate.longitude)
And I want to get the Value for Latitude.text and Longitude.text
in my Feedmodel.swift in this line here:
let postString = "firstName=19.4&lastName=-99.1";
So that I can do this here:
let postString = "firstName=\(Latitude.text)&lastName=\Longitude.text";
Hope you guys understood what I need and can help.
Thank You!

To pass your information from one view to another you have several options :
pass it through the segue (one to one)
use protocols & delegates (one to one)
use events & observers (one to many)
use a third class responsible for holding the current data (one to many)
In your case, using Protocols & Deleguates is the proper option to choose.
Example provided here.

Related

(Swift) API call is not going through first time, and on second attempt the call is made for the first tap

I an application that suppose to get weather data in certain cities and I have a dropdown and based on the dropdown selection, an api should be called (based on city name), when I tap on a city for the first time the app runs it returns nil and if I tap on another city it returns data based on the first selection, I have debugged and traced the code line by line however the URL is correct and the everything seems to be in order, any help? here is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var tempraturevalue: UILabel!
#IBOutlet weak var cityname: UILabel!
#IBOutlet weak var temprature: UIImageView!
#IBOutlet var cityButtons: [UIButton]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func handleSelection(_ sender: UIButton) {
cityButtons.forEach{ (button) in
UIView.animate(withDuration: 0.3) {
button.isHidden = !button.isHidden
self.view.layoutIfNeeded()
}
}
}
enum Cities:String {
case amman = "Amman"
case azzerqa = "Az zerqa"
case irbid = "Irbid"
case aqaba = "Aqaba"
}
var tempraturevalueData:Double = 0.0
var cityNameData:String = ""
#IBAction func cityTapped(_ sender: UIButton) {
guard let title = sender.currentTitle, let City = Cities(rawValue: title)
else {
return
}
var city:String
switch City {
case .amman:
city = "Amman"
case .azzerqa:
city = "zerqa"
case .irbid:
city = "Irbid"
case .aqaba:
city = "Aqaba"
}
let url = URL(string: "https://api.weatherapi.com/v1/current.json?key={key}&q=\(city)")
guard url != nil else {
print("error creating URL Object")
return
}
var request = URLRequest(url: url!, cachePolicy: .useProtocolCachePolicy , timeoutInterval: 10)
let headers = ["Content-Type" : "application/json"]
request.allHTTPHeaderFields = headers
request.httpMethod = "GET"
let session = URLSession.shared
let dataTask = session.dataTask(with: request, completionHandler: {(data, response, error) in
if error == nil && data != nil {
do {
let decoder = JSONDecoder()
do {
let weatherdatadecoded = try decoder.decode(WeatherData.self, from: data!)
self.tempraturevalueData = weatherdatadecoded.current?.temp_c ?? 0.1
self.cityNameData = weatherdatadecoded.location?.name ?? "no city found"
}
catch {
print(error)
}
}
catch {
print(error.localizedDescription)
}
}
})
dataTask.resume()
print(self.cityNameData)
print(self.tempraturevalueData)
}
}

Could not cast value of type '__NSDictionaryM' (0x1055952b0) to 'NSString' (0x1023e3c60)

I am using http://www.omdbapi.com/?t=pulp+fiction IMDB api for "pulp fiction" in my Code.
There is a search bar in the application and I write "pulp fiction" to this search bar then enter.
I get this error.
Could not cast value of type '__NSDictionaryM' (0x1055952b0) to
'NSString' (0x1023e3c60).
ViewController.swift:
//
// ViewController.swift
// IMDB Api Project
//
// Created by gurkan on 5.05.2017.
// Copyright © 2017 gurkan. All rights reserved.
//
import UIKit
class ViewController: UIViewController,UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var directorLabel: UILabel!
#IBOutlet weak var ratingLabel: UILabel!
#IBOutlet weak var actorsLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchForMovie(title: searchBar.text!)
searchBar.text = ""
}
func searchForMovie(title: String){
//http://www.omdbapi.com/?t=pulp+fiction
if let movie = title.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed){
let url = URL(string: "http://www.omdbapi.com/?t=\(movie)")
let session = URLSession.shared
let task = session.dataTask(with: url!, completionHandler: { (data, response, error) in
if error != nil {
print(error!)
} else {
if data != nil {
do {
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)
as! String //Error Line!
let jsonString = jsonResult.components(separatedBy: "")
let jsonDict = jsonString as! Dictionary<String,String>
DispatchQueue.main.async {
print(jsonDict)
}
} catch {
}
}
}
})
task.resume()
}
}
}
How can I solve this problem?
There's two things wrong.
First, this line force unwraps to a String
let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)
as! String
Simple remove as! String - it's not needed. Swift will infer the type and correctly create jsonResult.
Second, your code assumes that the JSON response coming back is a dictionary made up entirely of String names, and String values. Looking at the response from the url you posted, the object associated with the Ratings value is actually a dictionary. Since you are force unwrapping jsonString into a dictionary of strings, that will fail, since it is NOT a dictionary of strings. It's a dictionary of Strings and other stuff - a dictionary.
The easiest fix is:
Replace this line:
let jsonDict = jsonString as! Dictionary<String,String>
with
let jsonDict = jsonString as! [String: AnyObject]

Swift - How to get OpenWeatherMap JSON Data?

The following app should get the user's current location and then display the Name and Temperature of that location using OpenWeatherMap.
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var location: UILabel!
#IBOutlet weak var temperature: UILabel!
var locationManager: CLLocationManager = CLLocationManager()
var startLocation: CLLocation!
func extractData(weatherData: NSData) {
let json = try? NSJSONSerialization.JSONObjectWithData(weatherData, options: []) as! NSDictionary
if json != nil {
if let name = json!["name"] as? String {
location.text = name
}
if let main = json!["main"] as? NSDictionary {
if let temp = main["temp"] as? Double {
temperature.text = String(format: "%.0f", temp)
}
}
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let latestLocation: AnyObject = locations[locations.count - 1]
let lat = latestLocation.coordinate.latitude
let lon = latestLocation.coordinate.longitude
// Put together a URL With lat and lon
let path = "http://api.openweathermap.org/data/2.5/weather?lat=\(lat)&lon=\(lon)&appid=2854c5771899ff92cd962dd7ad58e7b0"
print(path)
let url = NSURL(string: path)
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) { (data, response, error) in
dispatch_async(dispatch_get_main_queue(), {
self.extractData(data!)
})
}
task.resume()
}
func locationManager(manager: CLLocationManager,
didFailWithError error: NSError) {
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
startLocation = nil
}
}
I've been learning how to get data from OpenWeatherMap following this tutorial:
https://www.youtube.com/watch?v=r-LZs0De7_U
The app crashes at:
self.extractData(data!)
as data is equal to nil, this shouldn't be happening as when I copy and paste the printed path into my web browser, the data is there. I'm sure I've followed the tutorial correctly, so what's the problem and how do I fix it?
The problem is with Transport Security - which causes issues for lots of us. Here's one of the SO answers explaining how to resolve it Transport security has blocked a cleartext HTTP
If you make the setting in your plist - set the NSAllowsArbitraryLoads key to YES under NSAppTransportSecurity dictionary in your .plist file - then it works.

Something like Callback in Swift

have a problem with my web service written in Swift.
Starting the web service runs perfectly and the method connectionDidFinishLoading (WebServiceHelper) gets the right data.
Now I wanna call an individual function (in this case in LoginViewController, later in other Controllers), depending on which function started the web service.
In JavaScript I would use callbacks, but can't find something like this in Swift documentation.
class WebServiceHelper: NSObject, NSURLConnectionDelegate, NSXMLParserDelegate {
var mutableData:NSMutableData = NSMutableData()
var sourceClass:String = ""
var lastUsedService:String = ""
func startWebServiceActivity(xmlMessage:String, method:String, service:String) {
let text: String = xmlMessage
let wsUrl: String = "https://.../webservice/soap/server.php"
let soapMessage:String = text
let url = NSURL(string: wsUrl)
let theRequest = NSMutableURLRequest(URL: url!)
let msgLength = String(soapMessage.characters.count)
theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length")
theRequest.HTTPMethod = "POST"
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
let connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
// Parse the result right after loading
func connectionDidFinishLoading(connection: NSURLConnection!) {
//print(mutableData)
let datastring = String(data: mutableData, encoding: NSUTF8StringEncoding)
//print(datastring)
let result = XMLParser.sharedParser.decode(datastring!)
print(result)
}
}
class LoginViewController: UIViewController {
//MARK: IBOutlets
#IBOutlet weak var usernameTextfield: UITextField!
#IBOutlet weak var passwordTextfield: UITextField!
#IBOutlet weak var autoLoginSwitch: UISwitch!
//MARK: Properties
var soapMethod:String = "login"
var username:String = ""
var password:String = ""
let soapMessages:SOAPMessages = SOAPMessages()
//MARK: Functions
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton
}
//MARK: IBActions
#IBAction func confirmButton(sender: UIButton) {
username = usernameTextfield.text!
password = passwordTextfield.text!
let loginXML:String = soapMessages.getLoginXML(username, password: password)
WebServiceHelper().startWebServiceActivity(loginXML,method: soapMethod, service:"login")
}
}
Thanks your your Help
Delegates are the other way of doing it, closures also preferred though

Cannot display part of JSON data

I've been trying to display certain JSON data to the storyboard but for some reason have been unable. The part of it that works, is the the var name, which is a string, and it doesn't have to be converted so it just works. The part that I am having an issue with is trying to convert two Int64's to strings, but I have them listed as AnyObjects. It's really confusing me, but here is the issue in code:
The program runs fine, but it doesn't display any information for profileIconId and summonerLevel.
import UIKit
class ViewController: UIViewController, NSURLConnectionDelegate {
lazy var data = NSMutableData()
#IBOutlet weak var searchField: UITextField!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var summonerLevel: UILabel!
#IBOutlet weak var profileIconId: UILabel!
#IBAction func enterButton(sender: AnyObject) {
startConnection()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startConnection(){
let urlPath: String = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/soon2challenger?api_key=(removed my private api key for obvious reasons)"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
let include: AnyObject = jsonResult.objectForKey(searchField.text)!
var name1: AnyObject = include.objectForKey("name")!
var summLevel: AnyObject = include.objectForKey("summonerLevel")!
var profIconId: AnyObject = include.objectForKey("profileIconId")!
name.text = name1 as? String
profileIconId.text = profIconId as? String
summonerLevel.text = summLevel as? String
println(name1)
println(summLevel)
println(profIconId)
}
}
The code that processes and displays everything is in the connectionDidFinishLoading function at the very bottom of the code.
Here's a refactor of your connectionDidFinishLoading(_:) method that properly unwraps the values using optional bindings.
You might also consider using NSNumberFormatter instead of "\()".
func connectionDidFinishLoading(connection: NSURLConnection) {
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary,
let include = jsonResult.objectForKey(searchField.text) as? NSDictionary {
if let name1 = include[ "name" ] as? String {
name.text = name1
println(name1)
}
if let summLevel = include[ "summonerLevel" ] as? NSNumber {
summonerLevel.text = "\(summLevel.integerValue)"
println(summLevel)
}
if let profIconId = include[ "profileIconId" ] as? NSNumber {
profileIconId.text = "\(profIconId.integerValue)"
println(profIconId)
}
}
}

Resources