How can I make these two functions work well together? - ios

I want to randomize the image background of weather depending on the weather information. I want to make them work one after the other;
the first function will make a string and the second function use the string produced by the first one.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var cityNameTextField: UITextField!
#IBOutlet weak var weatherFact: UILabel!
#IBOutlet weak var weatherImage: UIImageView!
var weather = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.cityNameTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func weatherButton(sender: UIButton) {
weatherInformation()
randomWeatherImage()
}
func showError() {
self.weatherFact.text = "we can't load the weather of \(cityNameTextField.text). please try again"
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.view.endEditing(true)
return true
}
func randomWeatherImage() {
if weatherFact.text != nil {
let string = weather
let regex = NSRegularExpression(pattern: "-?[0-9]{1,3}", options: NSRegularExpressionOptions(), error: nil)
if let matches = regex?.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location: 0, length: count(string))){
let degrees = matches.map { return(string as NSString).substringWithRange($0.range) }
var maxDegree = degrees[0].toInt()
var minDegree = degrees[1].toInt()
var averageWeather:Int = (maxDegree! + minDegree!) / 2
if averageWeather < 0 {
self.weatherImage.image = UIImage(named: "Cold.jpg")
}
else if averageWeather > 20 {
self.weatherImage.image = UIImage(named: "Warm.jpg")
}
else {
self.weatherImage.image = UIImage(named: "Mild.jpg")
}
}
}
}
func weatherInformation() {
let url = NSURL(string: "http://www.weather-forecast.com/locations/" + cityNameTextField.text.stringByReplacingOccurrencesOfString(" ", withString: "-") + "/forecasts/latest")
if url != nil {
let task = NSURLSession.sharedSession().dataTaskWithURL(url!){ (data, response, error) in
var urlError = false
if error == nil {
var urlContent = NSString(data: data, encoding: NSUTF8StringEncoding)
var urlContentArray = urlContent!.componentsSeparatedByString("<span class=\"phrase\">")
if urlContentArray.count > 0 {
var weatherArray = urlContentArray[1].componentsSeparatedByString("</span>")
self.weather = weatherArray[0] as! String
self.weather = self.weather.stringByReplacingOccurrencesOfString("°", withString: "º")
}
else {
urlError = true
}
}
else {
urlError = true
}
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = self.weather
}
}
}
task.resume()
}
else {
showError()
}
}
}

Just call randomWeatherImage after you set weatherFact.text:
dispatch_async(dispatch_get_main_queue()) {
if urlError == true {
self.showError()
}
else {
self.weatherFact.text = self.weather
self.randomWeatherImage()
}
}

Related

Swift : Delegate is nil

I've tried to build a delegate design pattern. I have a simple delegate in WeatherManager , but it's always nil.
I've tried to add weatherManager.delegate = self in override func viewDidLoad() of WeatherViewController.
However, I have another Protocol and delegate, which works fine.
I'm using the API to obtain geographic coordinates from city names, and the URL of the API to get information about the weather is created and executed.
WeatherManager
import Foundation
// delegate design parttern
protocol WeatherManagerDelegate:AnyObject {
func didUpdateWeather(inputWeatherModel: WeatherModel)
}
class WeatherManager {
// delegate
weak var delegate: WeatherManagerDelegate?
// fetchCoordinate
func fetchWeather(urlString: String) {
performRequest(inputURLString: urlString)
}
// performRequest
func performRequest(inputURLString: String) {
// 1. Create URL
if let url = URL(string: inputURLString) {
// 2. Create URLSession
let session = URLSession(configuration: .default)
// 3. Give the URLSession a task
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let safeData = data {
if let weather = self.parseJSON(JSONobject: safeData) {
// ---------------- problem here -------------------
self.delegate?.didUpdateWeather(inputWeatherModel: weather)
}
}
}
// 4. Start the task
task.resume()
}
}
// parse JSON object
func parseJSON(JSONobject: Data) -> WeatherModel? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(WeatherData.self, from: JSONobject)
let id = decodedData.weather[0].id
let temp = decodedData.main.temp
let name = decodedData.name
let weather = WeatherModel(conditionId: id, cityName: name, temperature: temp)
return weather
} catch {
print(error)
return nil
}
}
}
WeatherModel
import Foundation
struct WeatherModel {
let conditionId: Int
let cityName: String
let temperature: Double
var temperatureString: String {
return String(format: "%.1f", temperature)
}
var conditionName: String {
switch conditionId {
case 200...232:
return "cloud.bolt"
case 300...321:
return "cloud.drizzle"
case 500...531:
return "cloud.rain"
case 600...622:
return "cloud.snow"
case 701...781:
return "cloud.fog"
case 800:
return "sun.max"
case 801...804:
return "cloud.bolt"
default:
return "cloud"
}
}
}
WeatherViewController
import UIKit
class WeatherViewController: UIViewController, UITextFieldDelegate, WeatherManagerDelegate {
#IBOutlet weak var conditionImageView: UIImageView!
#IBOutlet weak var temperatureLabel: UILabel!
#IBOutlet weak var searchTextField: UITextField!
#IBOutlet weak var cityLabel: UILabel!
let weatherManager = WeatherManager()
var coordinateManager = CoordinateManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
searchTextField.delegate = self
searchTextField.keyboardType = .asciiCapable
weatherManager.delegate = self
}
#IBAction func searchPressed(_ sender: UIButton) {
searchTextField.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchTextField.endEditing(true)
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if textField.text != "" {
return true
} else {
textField.placeholder = "Type Something"
return false
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
if let city = searchTextField.text {
coordinateManager.fetchCoordinate(cityName: city)
}
searchTextField.text = ""
}
func didUpdateWeather(inputWeatherModel: WeatherModel) {
print(inputWeatherModel.temperature)
}
}
CoordinateManager
import Foundation
struct CoordinateManager {
// WeatherManager
let weathetManager = WeatherManager()
// geographical coordinates(lat, lon) 地理座標
let coordinateURL = "https://api.openweathermap.org/geo/1.0/direct?limit=1&appid=c8e60c6317c653a1789294c00f54ae19"
// fetchCoordinate
func fetchCoordinate(cityName: String) {
let urlString = "\(coordinateURL)&q=\(cityName)"
performRequest(inputURLString: urlString)
}
// transformURLString
func transformURLString(_ string: String) -> URLComponents? {
guard let urlPath = string.components(separatedBy: "?").first else {
return nil
}
var components = URLComponents(string: urlPath)
if let queryString = string.components(separatedBy: "?").last {
components?.queryItems = []
let queryItems = queryString.components(separatedBy: "&")
for queryItem in queryItems {
guard let itemName = queryItem.components(separatedBy: "=").first,
let itemValue = queryItem.components(separatedBy: "=").last else {
continue
}
components?.queryItems?.append(URLQueryItem(name: itemName, value: itemValue))
}
}
return components!
}
// performRequest
func performRequest(inputURLString: String) {
// 1. Create URL
let components = transformURLString(inputURLString)
if let url = components?.url {
// 2. Create URLSession
let session = URLSession(configuration: .default)
// 3. Give the URLSession a task
let task = session.dataTask(with: url) {(data, response, error) in
if error != nil {
print(error!)
return
}
if let safeData = data {
self.parseJSON(JSONobject: safeData)
}
}
// 4. Start the task
task.resume()
}
}
// parseJSON
func parseJSON(JSONobject: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode([CoordinateData].self, from: JSONobject)
let name = decodedData[0].name
let lat = decodedData[0].lat
let lon = decodedData[0].lon
let coordinateModel = CoordinateModel(name: name, lat: lat, lon: lon)
let weatherURL = coordinateModel.urlString
// ------- WeatherManager fetchWeather ---------
weathetManager.fetchWeather(urlString: weatherURL)
} catch {
print(error)
}
}
}
CoordinateModel
import Foundation
struct CoordinateModel {
let name: String
let lat: Double
let lon: Double
// wheather 地理座標を元に検索した天気の情報
let weatherstr = "https://api.openweathermap.org/data/2.5/weather?"
let str = "units=metric&appid=c8e60c6317c653a1789294c00f54ae19#"
// computedproperty
var urlString: String {
return "\(weatherstr)&lat=\(lat)&lon=\(lon)&\(str)"
}
}
You create a weatherManager in the WeatherViewController , and in the viewDidLoad method you set the WeatherViewController as a delegate to the weatherManager instance you created here. In the CoordinateManager class, you create a new weatherManager, and don't set a delegate for it.
2 solutions, use what is most convenient for you:
Create an initializer for the CoordinateManager, to pass it the WeatherManager that you have created and that you are listening to
// CoordinateManager class
let weatherManager: WeatherManager
init(weatherManager: WeatherManager) {
self.weatherManager = weatherManager
}
// WeatherViewController class
let weatherManager = WeatherManager()
var coordinateManager = CoordinateManager(weatherManager: weatherManager)
You can directly set WeatherViewController as a delegate to the desired weatherManager instance.
// WeatherViewController class
override func viewDidLoad() {
super.viewDidLoad()
searchTextField.delegate = self
searchTextField.keyboardType = .asciiCapable
// Instead weatherManager.delegate = self
coordinateManager.weatherManager.delegate = self
}

How to get the registered user Notification API data come for guest user too?

Current Scenario?:
Th registered user of the book app gets the notifications such as 'books available for download', q&A portal answers, live streaming link.
What is the goal?:
To get the notifications for guest where it can show the available books for download, and other notification that comes for registered user.
What is the issue/errors?:
When user clicks on the notification button , nothing comes on the screen. Everything blank and no notification is shown. It show the below error::
What i tried?:
When we call API, the token is generated from the backend. This token is then used to get the access. I tried to copy the API method to the home-screen that is used from 'signUpVC'(sign up view controller) to get the token bit showing above error.
Admin user notification looks as below:
Guest user (notification from our android app)
Code: for SignUp
import UIKit
import PKHUD
import SDWebImage
class SignupVC: ThemeController {
// MARK: - Outlets
#IBOutlet weak var imgProfile: TappableImageView!
#IBOutlet weak var passwordView: UIStackView!
#IBOutlet weak var lblRegister: UILabel!
var isFromUpdateProfile = Bool()
// -----------------------------------------------------------------------------------------------
// MARK: - Class Properties
#IBOutlet weak var txtFirstName: UITextField!
#IBOutlet weak var txtLastName: UITextField!
#IBOutlet weak var txtEmail: UITextField!
#IBOutlet weak var txtCity: UITextField!
#IBOutlet weak var txtPassword: UITextField!
// -----------------------------------------------------------------------------------------------
// MARK: - Memory Management Functions
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
deinit {
}
// -----------------------------------------------------------------------------------------------
// MARK: - Class Functions
private func errorsInTextFields() -> String? {
self.view.endEditing(true)
guard !txtFirstName.isEmpty else { return UserMessages.kBlankFirstName }
guard txtFirstName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidFirstName }
guard !txtLastName.isEmpty else { return UserMessages.kBlankLastName }
guard txtLastName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidLastName }
guard !txtEmail.isEmpty else { return UserMessages.kBlankEmail }
guard txtEmail.hasValid(.email) else { return UserMessages.kValidEmail }
guard !txtCity.isEmpty else { return UserMessages.kBlankCity }
guard txtCity.hasValid(.alphabetWithSpace) else { return UserMessages.kValidCity }
guard !txtPassword.isEmpty else { return UserMessages.kBlankPassword }
//guard txtPassword.hasValid(.password) else { return UserMessages.kValidPassword }
// No Errors
return nil
}
private func errorsInEditProfileTextFields() -> String? {
self.view.endEditing(true)
guard !txtFirstName.isEmpty else { return UserMessages.kBlankFirstName }
guard txtFirstName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidFirstName }
guard !txtLastName.isEmpty else { return UserMessages.kBlankLastName }
guard txtLastName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidLastName }
guard !txtEmail.isEmpty else { return UserMessages.kBlankEmail }
guard txtEmail.hasValid(.email) else { return UserMessages.kValidEmail }
guard !txtCity.isEmpty else { return UserMessages.kBlankCity }
guard txtCity.hasValid(.alphabetWithSpace) else { return UserMessages.kValidCity }
// No Errors
return nil
}
// -----------------------------------------------------------------------------------------------
// MARK: - Action Functions
#IBAction func btnRegisterAction(_ sender: RoundButton) {
if let _ = User.current?.accessToken{
//TextField Verification
if let error = errorsInEditProfileTextFields() {
SnackBar.show(error)
return
}
//API Calling
self.apiEditProfileCall()
}else{
//TextField Verification
if let error = errorsInTextFields() {
SnackBar.show(error)
return
}
//API Calling
apiRegisterDeviceCall()
}
}
// -----------------------------------------------------------------------------------------------
// MARK: - Web Service Functions
private func apiRegisterDeviceCall() {
HUD.show(.progress)
var deviceToken:String = UserDefaults.standard.string(forKey: "DeviceToken") ?? "empty"
let parameters: [String: Any] = [
"vDeviceUniqueId" : DeviceManager.deviceUniqueId,
"txDeviceToken" : deviceToken,
"tDeviceOs" : DeviceManager.deviceOS,
"vDeviceName" : DeviceManager.modelName,
"vResolution" : DeviceManager.resolution,
"vOsVersion" : DeviceManager.osVersion,
]
print(parameters)
APIManager.shared.makeRequest(method: .registerDevice, parameters: parameters, withLoader: false) { (response, error) in
print(response)
if let accessToken = response["data"]["access_token"].string {
UserDefaults.standard.setValue(accessToken, forKey: "AccessToken")
self.apiRegisterCall()
} else {
HUD.hide()
SnackBar.show("Something went wrong")
}
}
}
private func apiRegisterCall() {
let parameters: [String: Any] = [
"vFirstName" : txtFirstName.trimmedText,
"vLastName" : txtLastName.trimmedText,
"vEmail" : txtEmail.trimmedText,
"vPassword" : txtPassword.trimmedText,
"vCityName" : txtCity.trimmedText,
]
var images: [String: UIImage] = [:]
if let image = imgProfile.image {
images["txProfileImageUrl"] = image
}
APIManager.shared.makeRequest(method: .registerUser, parameters: parameters, imageParameters: images, withLoader: false) { (response, error) in
HUD.hide()
if response["data"].exists() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.popViewController()
}
// Alert.showWith("User Registered", message: "Please check your email inbox for varification email", positiveTitle: "Ok", shouldResignOnTouchOutside: false) { isOk in
// if isOk {
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
// self.popViewController()
// }
// }
// }
} else {
SnackBar.show(response["message"].stringValue)
}
}
}
private func apiEditProfileCall() {
HUD.show(.progress)
let parameters: [String: Any] = [
"vFirstName" : txtFirstName.trimmedText,
"vLastName" : txtLastName.trimmedText,
"vEmail" : txtEmail.trimmedText,
"vCityName" : txtCity.trimmedText,
]
var images: [String: UIImage] = [:]
if let image = imgProfile.image {
images["txProfileImageUrl"] = image
}
APIManager.shared.makeRequest(method: .editProfile, parameters: parameters, imageParameters: images, withLoader: false) { (response, error) in
HUD.hide()
if response["data"].exists(){
if let accessToken = User.current?.accessToken{
var updateUser = User(withJSON: response["data"])
updateUser.accessToken = accessToken
User.current = updateUser
SnackBar.show("Profile successfully updated.")
self.navigationController?.popViewControllers(viewsToPop: 2)
}
}else{
SnackBar.show(response["message"].stringValue)
}
}
}
// -----------------------------------------------------------------------------------------------
// MARK: - Life Cycle Functions
override func viewDidLoad() {
super.viewDidLoad()
if let _ = User.current?.accessToken{
self.passwordView.isHidden = true
self.lblRegister.text = "Update"
self.title = "Edit Profile"
self.imgProfile.sd_imageIndicator = SDWebImageActivityIndicator.gray
self.imgProfile.sd_setImage(with: URL(string: User.current!.profileImage), placeholderImage: nil)
self.txtFirstName.text = User.current!.firstName
self.txtLastName.text = User.current!.lastName
self.txtEmail.text = User.current!.email
self.txtCity.text = User.current!.cityName
}
}
// -----------------------------------------------------------------------------------------------
}

How to assign a value to a variable in a class from JSON or pass this value to the next function?

Hi everyone!
At the moment, I am taking a course at the Harvard computer science CS50.
My homework is almost ready, but has some incompleteness.
I cannot assign a value from a function to a variable in the class or pass
this value to the next function.
import UIKit
class PokemonViewController: UIViewController {
var url: String!
var name: String!
#IBOutlet var pokemonImage: UIImageView!
#IBOutlet var nameLabel: UILabel!
#IBOutlet var numberLabel: UILabel!
#IBOutlet var type1Label: UILabel!
#IBOutlet var type2Label: UILabel!
#IBOutlet var catchButton: UIButton!
#IBOutlet var descriptionLabel: UILabel!
// MARK: - additional properties
var currentDescURL: String!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadPokemon()
showPokemonDescription()
}
//MARK: - pokemon loading
func loadPokemon() {
guard let pokemonURL = URL(string: url) else { return }
URLSession.shared.dataTask(with: pokemonURL) { (data, _, error) in
guard let data = data else { return }
do {
let result = try JSONDecoder().decode(PokemonResult.self, from: data)
DispatchQueue.main.async {
self.navigationItem.title = self.capitalize(text: result.name)
self.nameLabel.text = self.capitalize(text: result.name)
self.numberLabel.text = String(format: "#%03d", result.id)
for typeEntry in result.types {
if typeEntry.slot == 1 {
self.type1Label.text = typeEntry.type.name
}
else if typeEntry.slot == 2 {
self.type2Label.text = typeEntry.type.name
}
}
// Create Image and Update ImageView
guard let imageURL = URL(string: result.sprites.front_default) else { return }
if let data = try? Data(contentsOf: imageURL) {
self.pokemonImage.image = UIImage(data: data)
}
self.currentDescURL = result.species.url
print(self.currentDescURL)
}
} catch let error { print(error) }
}.resume()
}
// MARK: - Get the URL of a specific Pokémon
func showPokemonDescription() {
guard let pokemonDescriptionURL = URL(string: currentDescURL) else { return }
URLSession.shared.dataTask(with: pokemonDescriptionURL) { (data, _, error) in
guard let data = data else { return }
do {
let result = try JSONDecoder().decode(PokemonDescription.self, from: data)
DispatchQueue.main.async {
// Check and get first pokemon description in English
for index in 0..<result.flavor_text_entries.count {
if result.flavor_text_entries[index].language.name == "en" {
self.descriptionLabel.text = result.flavor_text_entries[index].flavor_text
}
}
}
} catch let error { print(error) }
}.resume()
}
}
The first function loadPokemon() inside itself gets value from JSON and prints the value to the console -> print(self.currentDescURL). Moreover, if you display this value in viewWillAppear, then "nil" will be displayed in the console. I understand that the loadPokemon() function processes the values in the stream that occur at the very end. Perhaps because of this, the variable currentDescURL cannot get the value from the loadPokemon() function and the showPokemonDescription() function cannot use this value since currentDescURL is nil.
I ask you to explain to me what my mistake is and to help finish the assignment.
Move the call for method showPokemonDescription from viewWillAppear to loadPokemon after the currentDescURL property is set.
class PokemonViewController: UIViewController {
//...
var currentDescURL: String!
//...
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadPokemon()
getPreferences()
// <- remove the call from here
}
//...
func loadPokemon() {
//...
self.currentDescURL = result.species.url
self.showPokemonDescription() // <- move the call here
}
//...
func showPokemonDescription() {
//...
}
}

how to fix "missing argument label in call" in swift 3 [duplicate]

This question already has answers here:
Swift 3 first parameter names
(5 answers)
Closed 6 years ago.
i'm a totally beginner of swift and ios programming
and i met a question by following a coding lesson video which was written by swift 1 and xcode 6 beta.
i know the version of swift had changed ,and the syntax had been changed a lot two.
and i have fix some problems but there is still one that i can't deal with.
That's "missing argument label in call"
the following is my code:
import UIKit
import CoreLocation
class ViewController: UIViewController,CLLocationManagerDelegate {
let locationManger:CLLocationManager = CLLocationManager()
#IBOutlet weak var location: UILabel!
#IBOutlet weak var icon: UIImageView!
#IBOutlet weak var temperature: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManger.delegate = self
locationManger.desiredAccuracy = kCLLocationAccuracyBest
if(ios10()) {
locationManger.requestWhenInUseAuthorization()
}
locationManger.startUpdatingLocation()
}
func ios10() ->Bool {
return UIDevice.current.systemVersion == "10.2"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let location:CLLocation = locations[locations.count-1] as CLLocation
if(location.horizontalAccuracy > 0) {
print(location.coordinate.latitude)
print(location.coordinate.longitude)
self.updateWeatherInfo(latitude: location.coordinate.latitude,longitude: location.coordinate.longitude)
locationManger.stopUpdatingLocation()
}
}
func updateWeatherInfo(latitude:CLLocationDegrees,longitude:CLLocationDegrees){
let manager = AFHTTPRequestOperationManager()
let url = "http://api.openweathermap.org/data/2.5/weather?APPID=c5a8f49ee6e86f1aaa2be178f25f37f2"
let params = ["lat":latitude,"lon":longitude,"cnt":0]
manager.get(url,
parameters: params,
success: { (operation:AFHTTPRequestOperation!, responseObject: Any!) in
print("JSON:" + (responseObject as AnyObject).description!)
updateUISuccess(responseObject as! NSDictionary!)
//that's where my error1 :missing argument label 'jsonResult' in call
}
)
}
func updateUISuccess(jsonResult:NSDictionary){
if let tempResult = (jsonResult["main"] as? [String:Double])?["type"] {
//if let tempResult = (jsonResult["main"] as? [String:Double])?["type"] current
//if let tempResult = jsonResult["main"]?["temp"]? as? Double pre
var temperature:Double
if ((jsonResult["sys"] as? [String:String])?["country"] == "US"){
//CONVERT TO FAHRENHEIT IF USER IN US
temperature = round(((temperature - 273.15) * 1.8) + 32)
}
else{
//CONVERT TO CELSIUS
temperature = round(temperature - 273.15)
}
self.temperature.text = "\(temperature)°"
print(temperature)
var name = jsonResult["name"] as! String
self.location.text = "\(name)"
var conditionArray = (jsonResult["weather"] as! NSArray)[0] as! NSDictionary
var condition = conditionArray["id"] as! Int
var sunrise = (jsonResult["sys"] as? [String:Double])?["sunrise"]
var sunset = (jsonResult["sys"] as? [String:Double])?["sunset"]
var nightTime = false
var now = NSDate().timeIntervalSince1970
if (now < sunrise! || now > sunset!) {
nightTime = true
}
//self.icon.image = UIImage(named:"sunny")
updateWeatherIcon(condition,nightTime: nightTime)
//that's where my error2 :missing argument label 'condition:' in call
}
else {
print("error!")
}
}
func updateWeatherIcon(condition: Int,nightTime: Bool){
//thunderstorm
if(condition < 300) {
if nightTime {
self.icon.image = UIImage(named:"tstorm1_night")
}
else {
self.icon.image = UIImage(named:"tstorm1")
}
}
//drizzle
else if (condition < 500) {
}
//rain
else if (condition < 600) {
}
//snow
else if (condition < 700) {
}
//fog
else if (condition < 771) {
if nightTime {
self.icon.image = UIImage(named: "fog_night")
}
else {
self.icon.image = UIImage(named: "fog")
}
}
//tornado
else if (condition < 800) {
self.icon.image = UIImage(named:"tstorm3")
}
//clear
else if (condition == 800) {
if nightTime {
self.icon.image = UIImage(named:"sunny_night")
}
else {
self.icon.image = UIImage(named:"sunny")
}
}
//few clouds
else if (condition < 804) {
if nightTime {
self.icon.image = UIImage(named:"cloudy2_night")
}
else {
self.icon.image = UIImage(named:"cloudy2")
}
}
//overcast
else if (condition == 804) {
self.icon.image = UIImage(named:"overcast")
}
//extreme
else if ((condition >= 900 && condition < 903) || (condition >= 904 && condition < 1000)){
self.icon.image = UIImage(named:"tstorm3")
}
//cold
else if (condition == 903) {
self.icon.image = UIImage(named:"snow5")
}
//hot
else if (condition == 904) {
self.icon.image = UIImage(named:"sunny")
}
//dont know
else {
self.icon.image = UIImage(named:"dono")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error){
print(error)
}
}
i want to know how to fix it
thank you very much!
The error is because your function requires that you name the argument you are passing in. Try changing:
updateUISuccess(responseObject as! NSDictionary!)
To:
updateUISuccess(jsonResult: responseObject as! NSDictionary!)
Alternatively, you can define the function like this to not require the parameter to be named:
func updateUISuccess(_ jsonResult:NSDictionary){
Note the underscore.
Your second error has a similar cause, so change:
updateWeatherIcon(condition,nightTime: nightTime)
to:
updateWeatherIcon(condition: condition, nightTime: nightTime)

Searchbar with Async webservice call not reflect tableview reloadData()

I have tried to load search result on async call so search text won't take much time to enter.
it works on viewDidLoad but when i called up same method on searchbar text enter then it will go through reload data but not reflected on UI.It reflected when i click on cancel button of searchbar. I need to reflect reloadData on each search text entered on searchBar.
I have tried below code: Any help will be most appreciated.
import Foundation
import UIKit
class NSOperations {
lazy var downloadQueue:NSOperationQueue = {
var queue = NSOperationQueue()
queue.name = "Image Download queue"
queue.maxConcurrentOperationCount = 1
return queue
}()
lazy var filtrationQueue:NSOperationQueue = {
var queue = NSOperationQueue()
queue.name = "Search Filtration queue"
queue.maxConcurrentOperationCount = 1
return queue
}()
}
class SearchResultController: UIViewController, UITableViewDataSource, UITableViewDelegate,UISearchDisplayDelegate, UISearchBarDelegate
{
#IBOutlet var searchBar: UISearchBar!
#IBOutlet weak var contactsTableView: UITableView!
var genericArr = [Generic]()
var utility = Utility()
var constants = Constants()
var netUtil = NetworkUtil()
var controllerUtil = ControllerUtil()
var parser = Parsers()
var searchString = ""
var filteredTableData = [Generic]()
var searchActive : Bool = false
let pendingOperations:NSOperations = NSOperations()
override func viewDidLoad()
{
super.viewDidLoad()
self.contactsTableView.delegate = self
self.contactsTableView.dataSource = self
self.searchBar.delegate = self
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
filteredTableData.removeAll(keepCapacity: false)
self.filteredTableData = [Generic]()
if searchText != ""
{
searchActive = true
self.suspendAllOperations()
self.search(searchText)
}
else
{
searchActive = false
}
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false
self.searchBar.resignFirstResponder()
}
func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
var count:Int = 0
if self.searchActive == true {
count = self.filteredTableData.count
}
else{
count = self.genericArr.count
}
return count
}
func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
let resultCell = self.contactsTableView.dequeueReusableCellWithIdentifier("ResultCell") as! ResultCell
var result:Generic = Generic()
if searchActive == true && self.filteredTableData.count > 0
{
result = self.filteredTableData[indexPath.row]
resultCell.setResultCell(result)
}
else
{
result = self.genericArr[indexPath.row]
resultCell.setResultCell(result)
}
return resultCell
}
func suspendAllOperations () {
pendingOperations.downloadQueue.suspended = true
pendingOperations.filtrationQueue.suspended = true
}
func resumeAllOperations () {
pendingOperations.downloadQueue.suspended = false
pendingOperations.filtrationQueue.suspended = false
}
func search(searchTxt: String){
let searchUrl: String = "\(constants.SERVER_URL)\(constants.SEARCH_RESULT_URL)\(searchTxt.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)"
pendingOperations.filtrationQueue.addOperationWithBlock({
self.netUtil.callJSONData(searchUrl) {(dataDictionary) -> Void in
self.errorStr = dataDictionary[self.constants.defaultsKeys.RESPONSE_ERROR] as! String
let data: AnyObject? = dataDictionary[self.constants.defaultsKeys.RESPONSE_RESULT]
if(self.errorStr.isEmpty || self.errorStr==""){
if data != nil {
if let jsonNSData = data as? NSData
{
if let resultDict :NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(jsonNSData, options: NSJSONReadingOptions.MutableContainers)) as? NSDictionary{
self.loadData(resultDict)
print("count >> \(self.genericArr.count)")
dispatch_async(dispatch_get_main_queue()) {
self.contactsTableView.reloadData()
}
}
}
}
else{
// self.showError("something is wrong happened")
}
}
else{
// self.showError(self.errorStr)
}
}
})
}
func loadData(resultDict : NSDictionary){
let genArray:[Generic] = parser.getGenericArr(resultDict)
if searchActive == true{
self.filteredTableData = [Generic]()
self.filteredTableData.appendContentsOf(genArray)
}
else{
self.genericArr = [Generic]()
self.genericArr.appendContentsOf(genArray)
}
}
func callJSONData(urlStr: String, callback: ((data: Dictionary<String,AnyObject>) -> Void)!)
{
let url = NSURL(string: urlStr)!
var dict = Dictionary<String,AnyObject>()
var errorStr = ""
if let data = NSData(contentsOfURL: url) {
dict = Dictionary<String,AnyObject>()
self.parser.getJSONResultDataDictionary(data) {(dataDictionary) -> Void in
errorStr = dataDictionary[self.constants.defaultsKeys.RESPONSE_ERROR] as! String
if(errorStr.isEmpty || errorStr==""){
if let dataDict = dataDictionary[self.constants.defaultsKeys.RESPONSE_RESULT] as? Dictionary<String,AnyObject>
{
dict = dataDict
dict[self.constants.defaultsKeys.RESPONSE_ERROR] = errorStr
}
else{
dict[self.constants.defaultsKeys.RESPONSE_ERROR] = errorStr
}
}
else
{
dict[self.constants.defaultsKeys.RESPONSE_ERROR] = errorStr
}
}
}
else{
dict = Dictionary<String,AnyObject>()
dict[self.constants.defaultsKeys.RESPONSE_ERROR] = errorStr
}
callback(data: dict)
}
}

Resources