UITableView crashes at start at tableview.datasource - ios

I have implemented two UITableview in seperate ViewController classes. After successfully adding the code for the second UItableView my project builds but stops after loading.
It stops with a red line on:
tableView.delegate.dataSource = self
With an error that reads:
Thread 1 EXEC_BAD_INSTRUCTION (code-EXC_i386_INVOP,subcode=0x0)
AND
fatal error: unexpectedly found nil while unwrapping an Optional value
Since this didn't happen until adding the second UItableview in the second view controller I'm wondering if maybe my code is conflicting with each other. I will post copies of both view controllers. What should I change?
By the way: FilmsViewController is where the app is crashing. Although it was working prior to adding MCViewController Films:
B:
class FilmsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
weak var tableView : UITableView!
var FilmArray = [String]()
let film_url = "https://www.testing.com/api/resources/films/1"
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return FilmArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mycell", for:indexPath) as! FilmsAPITableViewCell
// Configuring Cell
cell.movieTitle.text = FilmArray[indexPath.row]
// Returning the cell
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
let url:URL = URL(string: film_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let paramString = ""
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
var json:Any?
do
{
if let existingData = data {
json = try JSONSerialization.jsonObject(with: existingData, options: [])
}
// Prasing JSON
if let parsedData = json as? [[String:Any]] {
for dict in parsedData {
if let title = dict["title"] as? String {
self.FilmArray.append(title)
print(json)
}
}
OperationQueue.main.addOperation({
self.tableView.reloadData()
})
}
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
// self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
// DispatchQueue.main.async(execute: self.LoginDone)
}
}
})
task.resume()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
MC:
class MCViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let message_url = "https://www.testing.com/api/resources/get_film_message/film_id/3825"
let send_url = "https://www.testing.com/api/resources/send_film_message"
let film_id = "3825"
var messageArray = [String]()
weak var tableView : UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messageArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "msgContent", for:indexPath) as! MessageTableViewCell
// Configuring Cell
cell.msgContent.text = messageArray[indexPath.row]
// Returning the cell
return cell
}
#IBOutlet weak var MessageInput: UITextField!
#IBAction func Sendmsg(_ sender: Any) {
Sendmsg(username:MessageInput.text!, password: film_id)
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// Do any additional setup after loading the view.
//let post_data: NSDictionary = NSMutableDictionary()
// post_data.setValue(username, forKey: "username")
// post_data.setValue(password, forKey: "password")
let url:URL = URL(string: message_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
// Do any additional setup after loading the view.
var paramString = ""
// for (key, value) in post_data
// {
// paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
// }
//
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
if let parsedData = json as? [[String:Any]] {
for dict in parsedData {
if let title = dict["message"] as? String {
self.messageArray.append(title)
print(json)
}
}
}
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
// self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
// DispatchQueue.main.async(execute: self.LoginDone)
}
}
})
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Sendmsg(username:String, password:String)
{
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(username, forKey: "message")
post_data.setValue(password, forKey: "film_id")
let url:URL = URL(string: send_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
print(json)
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
// if let data_block = server_response["data"] as? NSDictionary
// {
// if let session_data = data_block["session"] as? String
// {
// self.login_session = session_data
//
// let preferences = UserDefaults.standard
// preferences.set(session_data, forKey: "session")
//
// DispatchQueue.main.async(execute: self.LoginDone)
// }
// }
//
})
task.resume()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

Where are you initializing tableView? Seems like it might be nil....
tableView = UITableView(frame: frame)
If you're using storyboard/xib, you can also hook tableView up as an IBOutlet.

Related

how make REST API Call with Model class in swift 3 ios

i want to make REST API call in swift 3.0 with model classes of API code . Can any one help me to solved my issue?
let USER_LIST_FIRMWISE_URL = "\(BASE_URL2)user_list_firm_wise.php"
func userListFirmwiseRequest(firmid:String) -> URLRequest {
let Url = URL(string: (utility?.USER_LIST_FIRMWISE_URL)!)
var request = URLRequest(url: Url!)
request.httpMethod = "POST"
request.cachePolicy = .reloadIgnoringCacheData
let paramString = "firm_id=\(firmid)"
request.httpBody = paramString.data(using: String.Encoding.utf8)
return request
}
func getuserList() -> Void {
var request = mainApp.reqRes?.userListFirmwiseRequest(firmid: firmID)
request?.httpMethod = "POST"
print("request")
EZLoadingActivity.show("", disableUI: true)
let task = URLSession.shared.dataTask(with: request!) { (data: Data?, response: URLResponse?, error: Error?) in
DispatchQueue.main.async
{
do {
guard let data = data, error == nil else {
print("Error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200{
print("Status code should be 200, but is \(httpStatus.statusCode)")
print("Response String:\(String(describing: response))")
}
let jsonString = try? JSONSerialization.jsonObject(with: data, options: [])
guard let JsonObject = try? jsonString as AnyObject else{
return
}
guard let Success = try? JsonObject["success"] as! Int else{
return
}
print("Succee Resul :\(Success)")
if Success > 0{
guard let Message = try? JsonObject["message"] as Any else{
return
}
guard let JsonObjectForUser = try? Message as? AnyObject else {
return
}
}
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary ?? nil
if let parseJSON = json {
let dataDic = parseJSON.value(forKey: "message") as! NSMutableArray
self.arrayUserNameList = dataDic.value(forKey: "user_name") as! [String]
self.arrayUserData = dataDic
print(self.arrayUserNameList)
self.picker.reloadAllComponents()
EZLoadingActivity.hide()
}
} catch{
print(error)
EZLoadingActivity.hide()
}
}
}
task.resume()
}
i have used general code of NSurlsession for API call but it's too much code i have to write every time in every call. so i want common class for API CAll. but how to make common class for API call in swift 3.0
Try something like that
import Foundation
struct modelApi {
var arrayUserData: NSMutableArray = []
var arrayUserNameList: [String] = []
init(data:Data)
{
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary ?? nil
if let parseJSON = json
{
let dataDic = parseJSON.value(forKey: "message") as! NSMutableArray
self.arrayUserNameList = dataDic.value(forKey: "user_name") as! [String]
self.arrayUserData = dataDic
}
}
catch
{
print("Error")
}
}
}
import Foundation
class HttpRequest{
static let TIME_OUT_FOR_RESOURCE = 60.0
static let TIME_OUT_FOR_REQUEST = 30
static func sendHttpGetRequest(endPoint:String,responseMsg:#escaping (_ responseString:String?,_ error:String?)->Void) {
// let JSON_CONTENT_TYPE = "application/json"
// let HTTP_OK = 200
//Content Types
//1 ""Content-Type" = "text/html; charset=UTF-8";"
//2 "Content-Type" = "application/json";
let url = URL.init(string: endPoint)
let session = URLSession.shared
session.configuration.timeoutIntervalForRequest = TimeInterval(TIME_OUT_FOR_REQUEST)
session.configuration.timeoutIntervalForResource = TimeInterval(TIME_OUT_FOR_RESOURCE)
let task = session.dataTask(with: url!) {
data,
response ,
error in
guard error == nil
else{
responseMsg(nil,error!.localizedDescription)
return }
let responseString = String.init(data: data!, encoding: String.Encoding.utf8)!
responseMsg(responseString,nil)
}
task.resume()
}
static func setHttpPostRequest(endPoint:String,param:[String:Any],responseMsg:#escaping (_ responseJson:[String:Any]?,_ error:String?)->Void){
let url = URL.init(string:endPoint)
let session = URLSession.shared
session.configuration.timeoutIntervalForRequest = TimeInterval(TIME_OUT_FOR_REQUEST)
session.configuration.timeoutIntervalForResource = TimeInterval(TIME_OUT_FOR_RESOURCE)
var request = URLRequest.init(url: url!)
request.httpMethod = "POST"
do{
request.httpBody = try JSONSerialization.data(withJSONObject: param, options: .prettyPrinted)
}catch let error{
print(error)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
responseMsg(nil,error?.localizedDescription)
return
}
guard let data = data else {
responseMsg(nil,"Something went wrong")
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
responseMsg(json,nil)
// print(json)
// handle json...
}
} catch let error {
responseMsg(nil,error.localizedDescription)
// print(error.localizedDescription)
}
})
task.resume()
}}
BASEWEBSERVICE_ClASS:
// where RTCommonResponse is common response Model class. generated by ahmad ali json exporter tool.
import UIKit
import KRProgressHUD
import Foundation
import SystemConfiguration
protocol BaseWebserviceDelegate {
func sucessful(data : RTCommonResponse)
func failedWithMessage(message : String)
}
class BaseWebservice: NSObject
{
var webData : NSMutableData!
var statusCode : Bool!
var appDelegate : AppDelegate!
var baseDelegate : BaseWebserviceDelegate!
let opQueue = OperationQueue()
func initWithDelegate(aDelegate : BaseWebserviceDelegate) {
baseDelegate = aDelegate
appDelegate = UIApplication.shared.delegate as! AppDelegate
//return self
}
func callWithBaseRequest(requestData : Dictionary<String, Any>, aURL : String, method : String, showHUD : Bool ) {
let hudShow = showHUD && BaseWebservice.isInternetAvailable()
let url4 = URL(string: aURL as String)!
//let session4 = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: self.opQueue)
//let session4 = URLSession.shared
let session4: URLSession = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 9999
configuration.timeoutIntervalForResource = 9999
return URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
}()
let request = NSMutableURLRequest(url: url4)
request.httpMethod = method
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
//let paramString = "data=Hello"
//request.httpBody = paramString.data(using: String.Encoding.utf8)
if method == Constants.POST {
let cookieHeader = (requestData.flatMap({ (key, value) -> String in
return "\(key)=\(value)"
}) as Array).joined(separator: "&")
let postData : Data = cookieHeader.data(using: .utf8)!
request.httpBody = postData
AppDelegate.printLog(log: "Request started for url : " + aURL + " Peram : " + cookieHeader)
}
//request.addValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
let task = session4.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _: Data = data, let _: URLResponse = response, error == nil else {
print("*****error " + (error?.localizedDescription)!)
DispatchQueue.main.async {
KRProgressHUD.dismiss()
self.baseDelegate.failedWithMessage(message: (error?.localizedDescription)!)
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
return
}
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// print("*****This is the data 4: \(String(describing: dataString))") //JSONSerialization
let dictionary: Dictionary? = self.convertToDictionary(text: dataString! as String)
//let content = Content.init(fromDictionary: dictionary!)
AppDelegate.printLog(log:"Responce recived for url : " + aURL)
if dictionary == nil {
DispatchQueue.main.async {
KRProgressHUD.dismiss()
self.baseDelegate.failedWithMessage(message: "Something went wrong, try after some time")
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
return
}
//self.baseDelegate.sucessful(data: commonResponse)
DispatchQueue.main.async {
let commonResponse : RTCommonResponse = RTCommonResponse.init(fromDictionary: dictionary!)
if commonResponse.status == "ok" {
self.baseDelegate.sucessful(data: commonResponse)
KRProgressHUD.dismiss()
}else{
let error : RTError = RTError.init(fromDictionary: commonResponse.data!)
KRProgressHUD.dismiss()
self.baseDelegate.failedWithMessage(message: error.error)
}
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
//let task = session4.dataTask(with: request as URLRequest)
if hudShow {
DispatchQueue.main.async {
KRProgressHUD.show()
}
}
DispatchQueue.main.async {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
// session4
task.resume()
}
func convertToDictionary(text: String) -> [String: Any]? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch {
print(error.localizedDescription)
}
}
return nil
}
static func isInternetAvailable() -> Bool
{
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = flags.contains(.reachable)
let needsConnection = flags.contains(.connectionRequired)
return (isReachable && !needsConnection)
}
}
ForgotpasswordWS_Class:
// where RTForgotPasswordResponse is common response Model class. generated by ahamad ali json exporter tool.
import UIKit
protocol ForgotPasswordWebserviceDelegate {
func forgotPasswordSucessful(data : RTForgotPasswordResponse)
func forgotPasswordFailedWithMessage(message : String)
}
class ForgotPasswordWebservice: BaseWebservice {
var delegate : ForgotPasswordWebserviceDelegate!
init(aDelegate : ForgotPasswordWebserviceDelegate) {
super.init()
super.initWithDelegate(aDelegate: self as BaseWebserviceDelegate)
delegate = aDelegate
}
func initWithDelegate(aDelegate : ForgotPasswordWebserviceDelegate) {
super.initWithDelegate(aDelegate: self as BaseWebserviceDelegate)
delegate = aDelegate
//return self
}
func call(request : RTForgotPasswordRequest) {
let url = Constants.BASE_URL + "user/retrieve_password/"
self.callWithBaseRequest(requestData: request.toDictionary() , aURL: url, method: Constants.POST, showHUD: true)
}
}
extension ForgotPasswordWebservice : BaseWebserviceDelegate{
func sucessful(data : RTCommonResponse){
let content = RTForgotPasswordResponse.init(fromDictionary: data.data! )
//data.content = content
self.delegate.forgotPasswordSucessful(data: content)
}
func failedWithMessage(message : String){
self.delegate.forgotPasswordFailedWithMessage(message: message)
}
}
YourVIEWCONTROLLER_Class:
// just add extension to your view controller
extension yourViewController : ForgotPasswordWebserviceDelegate {
func forgotPasswordFailedWithMessage(message: String) {
let when = DispatchTime.now() + 1
DispatchQueue.main.asyncAfter(deadline:when){
self.showSnackBar(message: message)
}
}
func forgotPasswordSucessful(data: RTForgotPasswordResponse) {
let when = DispatchTime.now() + 1
DispatchQueue.main.asyncAfter(deadline:when) {
self.showSnackBar(message: data.msg)
//self.displayAlertMessage(messageToDisplay: "Reset Password Link Send")
}
}
}
// when you call API you have to write JUST line of CODE That's IT!!!
#IBAction func forgotbtntapped(_ sender: Any) {
let forgotws : ForgotPasswordWebservice = ForgotPasswordWebservice.init(aDelegate: self)
let forgotrequest : RTForgotPasswordRequest = RTForgotPasswordRequest();
forgotrequest.userLogin = forgotEmailTextField.text!
forgotws.call(request: forgotrequest)
}
Another simple way to call web API
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : CCell = self.tblV.dequeueReusableCell(withIdentifier: "cell") as! CCell
cell.lblName?.text = "ABCD"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func getClassList(completion: ((NSArray?, NSError?) -> Void)?) {
let myUrl = URL(string: "http://papili.us/studycentral/api/getClassList.php");
var request = URLRequest(url:myUrl!)
request.httpMethod = "POST"// Compose a query string
let postString = "";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
print("error=\(String(describing: error))")
completion?(nil, error as NSError?)
return
}
print("response = \(String(describing: response))")
//Convert response sent from a server side script to a NSDictionary object:
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
if json != nil {
let newdata : NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
let datalist : KRootClass = KRootClass.init(fromDictionary: newdata as! [String : Any])
print(datalist.classID)
print(datalist.className)
print(datalist.teacherTitle)
print(datalist.teacherLastName)
print(datalist.teacherFirstName)
}
} catch {
print(error)
completion?(nil, error as NSError)
}
}
task.resume()
}

Login function with activity indicator

I am currently doing a login test and have to log in again to log in. After pressing the login button to send the request to the server, the activity indicator is displayed on the screen until the activity indicator is stopped and the activity indicator is stopped The next page, I would like to open another thread used to implement the activity indicator, but I do not know how to implement, please help!
And this code is modified from http://www.kaleidosblog.com/how-to-create-a-login-screen-page-in-swift-3-authenticate-an-user-and-keep-the-session-active.
class ViewController: UIViewController {
let login_url = "http://www.kaleidosblog.com/tutorial/login/api/Login"
let checksession_url = "http://www.kaleidosblog.com/tutorial/login/api/CheckSession"
#IBOutlet var username_input: UITextField!
#IBOutlet var password_input: UITextField!
#IBOutlet var login_button: UIButton!
var login_session:String = ""
var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
override func viewDidLoad() {
super.viewDidLoad()
username_input.text = "try#me.com"
password_input.text = "test"
activityIndicator.hidesWhenStopped = true;
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray;
activityIndicator.center = view.center;
let preferences = UserDefaults.standard
if preferences.object(forKey: "session") != nil
{
login_session = preferences.object(forKey: "session") as! String
check_session()
}
}
#IBAction func DoLogin(_ sender: AnyObject) {
login_now(username:username_input.text!, password: password_input.text!)
}
#IBAction func backToMain(_ segue:UIStoryboardSegue){
let preferences = UserDefaults.standard
preferences.removeObject(forKey: "session")
self.dismiss(animated: true, completion: nil)
}
func login_now(username:String, password:String)
{
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(username, forKey: "username")
post_data.setValue(password, forKey: "password")
let url:URL = URL(string: login_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
DispatchQueue.main.async {
self.view.addSubview(self.activityIndicator)
}
}
}
})
task.resume()
LoginDone()
}
func check_session()
{
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(login_session, forKey: "session")
let url:URL = URL(string: checksession_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let response_code = server_response["response_code"] as? Int
{
if(response_code == 200)
{
DispatchQueue.main.async {
self.view.addSubview(self.activityIndicator)
}
}
else
{
}
}
})
task.resume()
}
func LoginDone()
{
self.performSegue(withIdentifier: "gotomenu", sender: nil)
}
func startActivityIndicator(){
activityIndicator.startAnimating()
}
func stopActivityIndicator() {
activityIndicator.stopAnimating()
}
}
Try to use SVProgressHUD. It's the simplest framework, that I have ever seen. SVProgressHUD on GitHub
Install:
In your podfile:
pod 'SVProgressHUD'
Then in terminal:
pod install
How to use:
import SVProgressHUD
to start:
SVProgressHUD.show()
to dismiss:
SVProgressHUD.dismiss()
Its very simple and usefull. Just try it.
Hope it helps
Replace this code code with old code:
class ViewController: UIViewController {
let login_url = "http://www.kaleidosblog.com/tutorial/login/api/Login"
let checksession_url = "http://www.kaleidosblog.com/tutorial/login/api/CheckSession"
#IBOutlet var username_input: UITextField!
#IBOutlet var password_input: UITextField!
#IBOutlet var login_button: UIButton!
var login_session:String = ""
var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
override func viewDidLoad() {
super.viewDidLoad()
username_input.text = "try#me.com"
password_input.text = "test"
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
activityIndicator.center = view.center
activityIndicator.isHidden = true
self.view.addSubview(self.activityIndicator)
let preferences = UserDefaults.standard
if preferences.object(forKey: "session") != nil
{
login_session = preferences.object(forKey: "session") as! String
check_session()
}
}
#IBAction func DoLogin(_ sender: AnyObject) {
login_now(username:username_input.text!, password: password_input.text!)
}
#IBAction func backToMain(_ segue:UIStoryboardSegue){
startActivityIndicator()
activityIndicator.isHidden = false
let preferences = UserDefaults.standard
preferences.removeObject(forKey: "session")
self.dismiss(animated: true, completion: nil)
stopActivityIndicator()
activityIndicator.isHidden = true
}
func login_now(username:String, password:String)
{
activityIndicator.isHidden = false
startActivityIndicator()
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(username, forKey: "username")
post_data.setValue(password, forKey: "password")
let url:URL = URL(string: login_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
self.stopActivityIndicator()
self.activityIndicator.isHidden = true
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
DispatchQueue.main.async {
self.LoginDone()
}
}
}
})
task.resume()
}
func check_session()
{
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(login_session, forKey: "session")
let url:URL = URL(string: checksession_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let response_code = server_response["response_code"] as? Int
{
if(response_code == 200)
{
DispatchQueue.main.async {
self.view.addSubview(self.activityIndicator)
}
}
else
{
}
}
})
task.resume()
}
func LoginDone()
{
self.performSegue(withIdentifier: "gotomenu", sender: nil)
}
func startActivityIndicator(){
activityIndicator.startAnimating()
}
func stopActivityIndicator() {
activityIndicator.stopAnimating()
}
}

How to populate TableView with jSON in Swift 3

Sorry guys it is lil old me again. I am reaching out as I need help with a second tableView I would like to implement in a another view controller. I have copied this code basically from another tableView controller which actually works. So I'm not sure where I messed up here but I would really appreciate the help.
class MCViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let message_url = "https://www.distribber.com/api/resources/get_film_message/film_id/3825"
let send_url = "https://www.distribber.com/api/resources/send_film_message"
let film_id = "3825"
var messageArray = [String]()
weak var messageView : UITableView!
func messageView(_ messageView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messageArray.count
}
func messageView(_ messageView: UITableView, cellForRowAt indexPath: IndexPath) -> MessageTableViewCell {
let cell = messageView.dequeueReusableCell(withIdentifier: "msgContent", for:indexPath) as! MessageTableViewCell
// Configuring Cell
cell.msgContent.text = messageArray[indexPath.row]
// Returning the cell
return cell
}
#IBOutlet weak var MessageInput: UITextField!
#IBAction func Sendmsg(_ sender: Any) {
Sendmsg(username:MessageInput.text!, password: film_id)
}
override func viewDidLoad() {
super.viewDidLoad()
messageView.dataSource = self
messageView.delegate = self
// Do any additional setup after loading the view.
//let post_data: NSDictionary = NSMutableDictionary()
// post_data.setValue(username, forKey: "username")
// post_data.setValue(password, forKey: "password")
let url:URL = URL(string: message_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "GET"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
// Do any additional setup after loading the view.
var paramString = ""
// for (key, value) in post_data
// {
// paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
// }
//
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
if let parsedData = json as? [[String:Any]] {
for dict in parsedData {
if let title = dict["message"] as? String {
self.messageArray.append(title)
print(json)
}
}
OperationQueue.main.addOperation({
self.messageView.reloadData()
})
}
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
if let data_block = server_response["data"] as? NSDictionary
{
if let session_data = data_block["session"] as? String
{
// self.login_session = session_data
let preferences = UserDefaults.standard
preferences.set(session_data, forKey: "session")
// DispatchQueue.main.async(execute: self.LoginDone)
}
}
})
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Sendmsg(username:String, password:String)
{
let post_data: NSDictionary = NSMutableDictionary()
post_data.setValue(username, forKey: "message")
post_data.setValue(password, forKey: "film_id")
let url:URL = URL(string: send_url)!
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.setValue("740c94c51891c02b64d6c78840b478fe0b02fe2c", forHTTPHeaderField: "X-API-KEY")
request.setValue("Basic YmhlZW0uZW5nckBnbWFpbC5jb206YmgzM20=", forHTTPHeaderField: "Authorization")
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in post_data
{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(
data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return
}
let json: Any?
do
{
json = try JSONSerialization.jsonObject(with: data!, options: [])
print(json)
}
catch
{
return
}
guard let server_response = json as? NSDictionary else
{
return
}
// if let data_block = server_response["data"] as? NSDictionary
// {
// if let session_data = data_block["session"] as? String
// {
// self.login_session = session_data
//
// let preferences = UserDefaults.standard
// preferences.set(session_data, forKey: "session")
//
// DispatchQueue.main.async(execute: self.LoginDone)
// }
// }
//
})
task.resume()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
You're implementing UITableViewDataSource but not implementing it's required methods.
func tableView(UITableView, cellForRowAt: IndexPath)
func numberOfSections(in: UITableView)
Implement those two and the not conforming to protocol error should go away.

pass id to another screen to display the particular id - product and its details

I have one collection view which have to display only the category name and its image. And i am showing this category name, image by doing some api calling. And also for each category name i will get the customer id for each category name. Here is the full code for that
func apicalling () {
let headers = [
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "7adebcbe-18b4-d2a7-2159-2fbcaea27edd"
]
let parameters = [
"customerID": "1",
"listType": "2"
]
do {
let postData = try JSONSerialization.data(withJSONObject: parameters, options :[])
let request = NSMutableURLRequest(url: NSURL(string: "http://example/categoryname.php")! as URL,
cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
///print(error)
} else {
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? Dictionary<String,AnyObject>
{
let status = json["status"] as? Int;
if(status == 1)
{
//print("SUCCESS....")
if let typeValues = json["categories"] as? [NSDictionary]
{
DispatchQueue.main.async(execute: {
// print("INSIDE CATEGORIES")
for item in typeValues
{
// print("INSIDE LISTING ITEMS...")
self.BTdata.append(BTData(json:item))
}
//print(self.BTdata[0].BTNames)
self.collectionView!.reloadData()
})
}
}
}
})
}
})
dataTask.resume()
} catch {
// print("JSON serialization failed: \(error)")
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return BTdata.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.CatName.text = BTdata[(indexPath as NSIndexPath).row].BTNames
let imgURL: URL = URL(string: BTdata[(indexPath as NSIndexPath).row].BTImage!)!
let request: URLRequest = URLRequest(url: imgURL)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
cell.ProductImg.image = UIImage(data:data!)
}
DispatchQueue.main.sync(execute: display_image)
}
})
task.resume()
return cell
}
func getIndexPathForSelectedCell() -> IndexPath?
{
var indexPath:IndexPath?
if collectionView.indexPathsForSelectedItems!.count > 0 {
indexPath = collectionView.indexPathsForSelectedItems![0]
}
return indexPath
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "showDetails"
{
if let indexPath = getIndexPathForSelectedCell()
{
let ContainerviewController = segue.destination as! DetailVC
ContainerviewController.BTdata = [BTdata[(indexPath as NSIndexPath).row]]
print("Printing value on collection click.....")
print(BTdata[(indexPath as NSIndexPath).row].BTIds)
}
}
}
And form my above code you can see that, i have done the segue to another view controller. And i am passing the ID to another view controller.In another view controller, i need to display the product items that user select in my first view controller.
In my second view controller, i have done some api to show all product .So the flow is :
When user press any category name in my first view controller, it have to go to second view controller and should so the particular product for the selected category name. Here is the code of my second VC :
Here i am getting the id from my first vc that user clicked any category name :
override func viewDidLoad() {
super.viewDidLoad()
self.BTypeId = BTdata[0].BTIds
Allproductapicalling ()
}
func Allproductapicalling () {
let headers = [
"content-type": "application/json",
"cache-control": "no-cache",
"postman-token": "c98d0000-637b-1efc-8f93-f9e277ffefcd"
]
let parameters = [
"customerID": "1",
"listType": "1"
]
do {
let postData = try JSONSerialization.data(withJSONObject: parameters, options :[])
let request = NSMutableURLRequest(url: NSURL(string: "http://exp.php")! as URL,
cachePolicy: .useProtocolCachePolicy,timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
///print(error)
} else {
DispatchQueue.main.async(execute: {
if let json = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? Dictionary<String,AnyObject>
{
let status = json["status"] as? Int;
if(status == 1)
{
print("SUCCESS....")
if let typeValues = json["products"] as? [NSDictionary]
{
DispatchQueue.main.async(execute: {
print("INSIDE CATEGORIES")
for item in typeValues {
let bId = item.value(forKey: "categoryID") as! String
if(bId == self.BTypeId) {
self.Productdata.append(ProductData(json:item))
}
}
})
//print("Product Name : ", self.Productdata[0].proName)
}
}
}
})
}
})
dataTask.resume()
} catch {
// print("JSON serialization failed: \(error)")
}
}
My problem is in this line from above api calling code :
if let typeValues = json["products"] as? [NSDictionary]
{
DispatchQueue.main.async(execute: {
for item in typeValues {
let bId = item.value(forKey: "categoryID") as! String
if(bId == self.BTypeId) {
self.Productdata.append(ProductData(json:item))
}
}
})
i am getting the selected category id from my first VC, and i am comparing with the all product api calling category id. And i need to display that particular product alone.How to do that ??
if(bId == self.BTypeId)
Please help me out.
Thanks
DispatchQueue.main.async(execute: {
for item in typeValues {
let bId = item.value(forKey: "categoryID") as! String
if(bId as? String == self.BTypeId) {
print("Hurray sathish......")
self.Productdata.append(ProductData(json:item))
// print(self.Productdata.append(bId))
}
}
self.Collectionview.delegate = self
self.Collectionview.dataSource = self
self.Collectionview.reloadData()
})
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! DetailCollectionviewcell
cell.DetailProductName.text = Productdata[indexPath.row].proDescription
let imgURL: URL = URL(string: Productdata[indexPath.row].proImage!)!
let request: URLRequest = URLRequest(url: imgURL)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) -> Void in
if (error == nil && data != nil)
{
func display_image()
{
cell.DetailImage.image = UIImage(data:data!)
}
DispatchQueue.main.sync(execute: display_image)
}
})
task.resume()
return cell
}
Your Output :
Your problem solve approve answer and give up vote thank you.
Happy Coding.

trying to make HTTP get request work on swift

I am relatively new to swift. As for now, I need to display the mysql datas to table view in my app. I have already prepared by json data which looks like
[{"restaurantnames":"restaurant 1","type":"type 1","location":"location 1"},{"restaurantnames":"restaurant 2","type":"type 1","location":"location 1"}]
Now I need to read json response and and populate my table view with these datas on app launch. For now, I have populated my table rows with the static data. I am trying to make use of this module for the GET request. This my RestaurantViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "http://localhost:8888/restaurant/registeruser.php")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "GET"
request.timeoutInterval = 60
NSURLSession.sharedSession().dataTaskWithURL(request, completionHandler: { (data:NSData!, respone:NSURLResponse!, error:NSError!) -> Void in
dispatch_async(dispatch_get_main_queue()){
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil!) as? NSDictionary
}
})
}
class ViewController: UIViewController {
var restName:Array< String > = Array < String >()
var restType:Array< String > = Array < String >()
override func viewDidAppear(animated: Bool) {
get_data_from_url("http://localhost:8888/restaurant/registeruser.php")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return restName.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "CategoryTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CategoryTableViewCell
cell.categoryName.text = restName[indexPath.row]
cell.Name.text = restType[indexPath.row]
return cell
}
func get_data_from_url(url:String) {
var url:NSURL = NSURL(string: url)!
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)
if urlData != nil && reponseError == nil {
let res = response as! NSHTTPURLResponse!;
//NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300) {
var responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
//NSLog("Response ==> %#", responseData);
extract_json(urlData!)
} else {
var alertView:UIAlertView = UIAlertView()
alertView.title = "Sign in Failed!"
alertView.message = "Connection Failed"
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
} else {
var alertView:UIAlertView = UIAlertView()
alertView.title = "Sign in Failed!"
alertView.message = "Connection Failure"
if let error = reponseError {
alertView.message = (error.localizedDescription)
}
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
}
func extract_json(data:NSData) {
var error: NSError?
let jsonData: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers , error: &error)
if (error == nil) {
if let rest_cat_list = jsonData as? NSArray
{
for (var i = 0; i < rest_cat_list.count ; i++ )
{
if let rest_obj = rest_cat_list[i] as? NSDictionary
{
if let restaurant = rest_obj["restaurantnames"] as? String
{
restName.append(restaurant)
if let restType = rest_obj["type"] as? String
{
restType.append(restType)
}
}
}
}
}
}
do_table_refresh();
}
func do_table_refresh() {
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}
}
First go to this site and validate your URL
https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?utm_source=chrome-app-launcher-info-dialog ( GOOGLE extenstion )
then replace below given values according to your settings :-
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("*/*", forHTTPHeaderField: "Accept")

Resources