Update CLLocation Manager on another method - cllocationmanager

I need to update my location outside the func locationManager
I have 2 labels that are being updated every second, and a call to an API from a HTTP POST Request. The problem is when I call the API (when I press the startButton, only the first value is passed :-/
class PressStartViewController: UIViewController,CLLocationManagerDelegate {
var manager: CLLocationManager!
var userLocation: CLLocation! = nil
var timer = NSTimer()
var time = 0
var minute = 0
#IBOutlet var bearingLabel: UILabel!
#IBOutlet var speedlabel: UILabel!
#IBOutlet var timerLabel: UILabel!
#IBOutlet var minuteLabel: UILabel!
#IBOutlet var startButton: UIButton!
#IBOutlet var startImage: UIImageView!
#IBOutlet var finishImage: UIImageView!
#IBOutlet var resumeImage: UIImageView!
func increaseTimer() {
time++
if time > 9 {
timerLabel.text = "\(time)"
} else {
timerLabel.text = "0\(time)"
}
if time > 59 {
time = 0
timerLabel.text = "00"
minute++
if minute > 9 {
minuteLabel.text = "\(minute)"
} else {
minuteLabel.text = "0\(minute)"
}
}
}
#IBAction func start(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("increaseTimer"), userInfo: nil, repeats: true)
startImage.hidden = true
resumeImage.hidden = false
finishImage.hidden = false
sendPosition()
}
#IBAction func resume(sender: AnyObject) {
timer.invalidate()
startImage.hidden = false
resumeImage.hidden = true
finishImage.hidden = true
}
#IBAction func finish(sender: AnyObject) {
timer.invalidate()
time = 0
minute = 0
timerLabel.text = "00"
minuteLabel.text = "00"
}
override func viewDidLoad() {
super.viewDidLoad()
// print ("ent viewdidload")
// Do any additional setup after loading the view.
//print (userId!)
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingHeading()
manager.startUpdatingLocation()
resumeImage.hidden = true
finishImage.hidden = true
}
func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
let heading = newHeading.magneticHeading
self.bearingLabel.text = String(format: "%.0fº",heading)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
userLocation = locations[0]
let bearing = userLocation.course
let knots = userLocation.speed
//self.bearingLabel.text = String(format: "%.0fº",bearing)
self.speedlabel.text = String(format: "%.1f knots",knots * 1.94384)
// print(locations)
}
func sendPosition() {
manager.startUpdatingLocation()
manager.startUpdatingHeading()
let Speed = userLocation.speed
let Bearing = userLocation.course
let Latitude = userLocation.coordinate.latitude
let Longitude = userLocation.coordinate.longitude
let clientTimestamp = NSDate().iso8601
let BoxId = UIDevice.currentDevice().identifierForVendor!.UUIDString
let SessionId = NSUUID().UUIDString
let Bearer = userId!
let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
spinningActivity.labelText = "Loading"
spinningActivity.detailsLabelText = "Please wait"
let myUrl = NSURL(string: "https://www.example.com/api/v1/positions/");
let request = NSMutableURLRequest(URL:myUrl!,cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0);
request.HTTPMethod = "POST";
let postString = "Speed=\(Speed)&Bearing=\(Bearing)&Latitude=\(Latitude)&Longitude=\(Longitude)&clientTimestamp=\(clientTimestamp)&BoxId=\(BoxId)&SessionId=\(SessionId)"
//print (postString)
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
request.setValue("Bearer \(Bearer)", forHTTPHeaderField: "Authorization")
/////////////////
print (Bearer)
//print (request)
NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
print (response!)
dispatch_async(dispatch_get_main_queue())
{
spinningActivity.hide(true)
if(error != nil)
{
//Display an alert message
let myAlert = UIAlertController(title: "Alert", message: error!.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert);
let okAction = UIAlertAction(title: "OK1", style: UIAlertActionStyle.Default, handler:nil)
myAlert.addAction(okAction);
self.presentViewController(myAlert, animated: true, completion: nil)
return
}
do {
print ("linha 1")
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
if let parseJSON = json {
print ("linha 3")
// let userId = parseJSON["access_token"] as? String
// if(userId != nil)
// {
// print ("linha 4")
// // NSUserDefaults.standardUserDefaults().setObject(parseJSON["userFirstName"], forKey: "userFirstName")
// // NSUserDefaults.standardUserDefaults().setObject(parseJSON["userLastName"], forKey: "userLastName")
// NSUserDefaults.standardUserDefaults().setObject(parseJSON["access_token"], forKey: "userId")
// NSUserDefaults.standardUserDefaults().synchronize()
//
// // take user to a protected page
// /*
// let mainPage = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as! MainPageViewController
//
// let mainPageNav = UINavigationController(rootViewController: mainPage)
// let appDelegate = UIApplication.sharedApplication().delegate
//
// appDelegate?.window??.rootViewController = mainPageNav
// */
//
// let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
//
// appDelegate.buildNavigationDrawer()
//
//
// } else {
// print ("linha 5")
// // display an alert message
// let userMessage = parseJSON["message"] as? String
// let myAlert = UIAlertController(title: "Alert", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert);
// let okAction = UIAlertAction(title: "OK2", style: UIAlertActionStyle.Default, handler:nil)
// myAlert.addAction(okAction);
// self.presentViewController(myAlert, animated: true, completion: nil)
// }
// print ("linha 6")
}
} catch
{
print(error)
}
}
}).resume()
}

I did it myself, I had a new timer and call sendPosition every x seconds
It's working

Related

Image doesn't upload to firebase storage, swift

Here is the code
import UIKit
import Photos
import Firebase
import FirebaseStorage
class SignUpViewController: UIViewController {
#IBOutlet weak var userNameTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var errorLabel: UILabel!
#IBOutlet weak var tapToChangeButton: UIButton!
#IBOutlet weak var profileImageView: UIImageView!
var imagePickerController = UIImagePickerController()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
userNameTextField.backgroundColor = .clear
userNameTextField.layer.cornerRadius = 27
userNameTextField.layer.borderWidth = 1
userNameTextField.layer.borderColor = UIColor.systemGreen.cgColor
emailTextField.backgroundColor = .clear
emailTextField.layer.cornerRadius = 27
emailTextField.layer.borderWidth = 1
emailTextField.layer.borderColor = UIColor.systemGreen.cgColor
passwordTextField.backgroundColor = .clear
passwordTextField.layer.cornerRadius = 27
passwordTextField.layer.borderWidth = 1
passwordTextField.layer.borderColor = UIColor.systemGreen.cgColor
let imageTap = UITapGestureRecognizer(target: self, action: #selector(openImagePicker))
profileImageView.isUserInteractionEnabled = true
profileImageView.addGestureRecognizer(imageTap)
profileImageView.layer.cornerRadius = profileImageView.bounds.height / 2
profileImageView.clipsToBounds = true
tapToChangeButton.addTarget(self, action: #selector(openImagePicker), for: .touchUpInside)
imagePickerController = UIImagePickerController()
imagePickerController.allowsEditing = true
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
checkPermissions()
}
#objc func openImagePicker(_ sender:Any) {
// Open Image Picker
self.present(imagePickerController, animated: true, completion: nil)
}
func checkPermissions() {
if PHPhotoLibrary.authorizationStatus() != PHAuthorizationStatus.authorized {
PHPhotoLibrary.requestAuthorization({ (status:
PHAuthorizationStatus) -> Void in
()
})
}
if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized {
} else {
PHPhotoLibrary.requestAuthorization(requestAuthorizationHandler)
}
}
func requestAuthorizationHandler(status: PHAuthorizationStatus) {
if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized {
print("Have authorization")
} else {
print("Authorization declined")
}
}
After pressing the signUp button the uploadToCloud function should be performed but I don't know how to fetch the url from image picker
#IBAction func signupPressed(_ sender: UIButton) {
guard let username = self.userNameTextField.text, username.count > 3 else {
self.errorLabel.text = "Please enter a valid username"
return
}
guard let password = passwordTextField.text else {
self.errorLabel.text = "Please enter a valid password"
return
}
guard let email = emailTextField.text else {
self.errorLabel.text = "Please enter a valid email"
return
}
Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
if let e = error {
self.errorLabel.text = e.localizedDescription
} else {
//Navigate to the ChatViewController
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["username": username, "uid": authResult!.user.uid]) { (error) in
if let e = error {
// You may not want to show this error to the user but you should still show a "sanitised" error so that it doesn't leak information.
self.errorLabel.text = e.localizedDescription
} else {
self.performSegue(withIdentifier: "goToMap", sender: self)
}
}
}
}
}
func uploadToCloud(fileURL: URL) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let storage = Storage.storage()
let data = Data()
let storageRef = storage.reference()
let localFile = fileURL
let photoRef = storageRef.child("users/\(uid)")
let uploadTask = photoRef.putFile(from: localFile, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
self.errorLabel.text = error?.localizedDescription
return
}
metadata.contentType = "image/jpg"
}
}
}
extension SignUpViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
self.profileImageView.image = pickedImage
}
if let url = info[UIImagePickerController.InfoKey.imageURL] as? URL {
uploadToCloud(fileURL: url)
}
picker.dismiss(animated: true, completion: nil)
}
}
I don't understand your problem well, But I think the problem is your
uploadToCloud function.
This is another version of your function which is more easier to me
func uploadToCloud(with profileImage:UIImage){
let storage = Storage.storage().reference()
guard let uid = Auth.auth().currentUser?.uid else { return }
guard let imageData = profileImage.pngData() else{
return
}
storage.child("users/\(uid)").putData(imageData, metadata: nil) { (StorageMetadata, error) in
guard StorageMetadata != nil else{
print("oops an error occured while data uploading")
return
}
print("Image sent")
}
}

UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger

I am trying to create a seat map layout functionality that takes the coordinates and create a map i want to provide the value of the sections that the map contains. I am using custom collectionViewLayout to create the cells but i am getting that error in the title .
Here is my protocol-
protocol SeatMapDelegate: class {
func getSectionCoordinates() -> [Int]
}
Definition -
func getSectionCoordinates() -> [Int] {
return sectionHeader
}
and then i am assigning the values to the array
var sectionHeader = [Int]()
sectionHeader=(delegate?.getSectionCoordinates())!
below code is my project for search and find coordinate on the map:
Maybe help you
// ViewController.swift
// MapKit Starter
//
// Created by Ehsan Amiri on 10/25/16.
// Copyright © 2016 Ehsan Amiri. All rights reserved.
//
import UIKit
import MapKit
import Foundation
class ViewController: UIViewController {
#IBOutlet var mapView: MKMapView?
#IBOutlet weak var text: UITextField!
var index = 0
var indexx = 0
let locationManager = CLLocationManager()
var picName:String?
var place :MKAnnotation?
var places = [Place]()
var place1 :MKAnnotation?
var places1 = [Place]()
override func viewDidLoad() {
super.viewDidLoad()
//downpic()
self.requestLocationAccess()
}
override func viewWillAppear(_ animated: Bool) {
let defaults = UserDefaults.standard
let age = defaults.integer(forKey: "maptype")
switch (age) {
case 0:
mapView?.mapType = .standard
case 1:
mapView?.mapType = .satellite
case 2:
mapView?.mapType = .hybrid
default:
mapView?.mapType = .standard
}
}
#IBAction func info(_ sender: Any) {
}
override var prefersStatusBarHidden: Bool {
return true
}
func requestLocationAccess() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedAlways, .authorizedWhenInUse:
return
case .denied, .restricted:
print("location access denied")
default:
locationManager.requestWhenInUseAuthorization()
}
}
#IBAction func textField(_ sender: Any) {
mapView?.removeOverlays((mapView?.overlays)!)
mapView?.removeAnnotations((mapView?.annotations)!)
self.server()
_ = Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(self.server), userInfo: nil, repeats: true)
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
if self.indexx != 0 {
self.addAnnotations()
self.addPolyline()
}
}
}
#objc func server() {
place = nil
places = [Place]()
place1 = nil
places1 = [Place]()
indexx = 0
let id = text.text
print("id=\(id!)")
let url = URL(string: "my server")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let postString = "id=\(id!)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data 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))")
let stringgg = "notFound\n\n\n\n"
if responseString == stringgg {
print(stringgg)
}else{
let json = try! JSONSerialization.jsonObject(with: data, options: [])
let betterJSON = json as! NSArray
let jsonCount = betterJSON.count
print(betterJSON)
for item in betterJSON {
self.indexx += 1
let dictionary = item as? [String : Any]
let title = dictionary?["title"] as? String
let subtitle = dictionary?["description"] as? String
let latitude = dictionary?["latitude"] as? Double ?? 0, longitude = dictionary?["longitude"] as? Double ?? 0
self.place = Place(title: title, subtitle: subtitle, coordinate: CLLocationCoordinate2DMake(latitude , longitude ))
self.places.append(self.place as! Place)
print("latttt",longitude)
if self.indexx == 1{
let shipid = UserDefaults.standard
shipid.set(title, forKey: "origin")
shipid.set(subtitle, forKey: "date")
}
if jsonCount == self.indexx{
let shipid = UserDefaults.standard
shipid.set(title, forKey: "location")
self.place1 = Place(title: title, subtitle: subtitle, coordinate: CLLocationCoordinate2DMake(latitude , longitude ))
self.places1.append(self.place1 as! Place)
}
}
}
}
task.resume()
let when = DispatchTime.now() + 1.5
DispatchQueue.main.asyncAfter(deadline: when) {
if self.indexx != 0 {
self.addAnnotations()
self.addPolyline()
}
}
}
func addAnnotations() {
print("hhhh",places)
mapView?.delegate = self
mapView?.removeAnnotations((mapView?.annotations)!)
mapView?.addAnnotations(places1)
let overlays = places1.map { MKCircle(center: $0.coordinate, radius: 100) }
mapView?.addOverlays(overlays)
}
func addPolyline() {
var locations = places.map { $0.coordinate }
let polyline = MKPolyline(coordinates: &locations, count: locations.count)
// print("Number of locations: \(locations.count)")
index = locations.capacity
mapView?.add(polyline)
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
else {
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "annotationView") ?? MKAnnotationView()
annotationView.image = UIImage(named:"place icon")
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.canShowCallout = true
return annotationView
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKCircle {
let renderer = MKCircleRenderer(overlay: overlay)
renderer.fillColor = UIColor.black.withAlphaComponent(0.5)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 2
return renderer
} else if overlay is MKPolyline {
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = UIColor.orange
renderer.lineWidth = 2
return renderer
}
return MKOverlayRenderer()
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//guard let annotation = view.annotation as? Place, let title = annotation.title else { return }
let shipidname = text.text
let shipid = UserDefaults.standard
shipid.set(shipidname, forKey: "shipid")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "shipinfo")
self.present(secondViewController, animated: true, completion: nil)
}
}

Login & Signup iOS Swift - Core Data

I want to create login and signup functions within Swift using Core Data.
This is my code to store the data in the signupVC;
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDel.managedObjectContext
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
newUser.setValue(txtUsername.text, forKey: "username")
newUser.setValue(txtPassword.text, forKey: "password")
newUser.setValue(txtEmailAdd.text, forKey: "email")
do {
try context.save()
} catch {}
print(newUser)
print("Object Saved.")
This is the code in the LoginVC;
#IBAction func signinTapp(sender: UIButton) {
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDel.managedObjectContext
let request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
request.predicate = NSPredicate(format: "username = %#", "" + txtUsername.text!)
let results:NSArray = try! context.executeFetchRequest(request)
if(results.count > 1){
let res = results[0] as! NSManagedObject
txtUsername.text = res.valueForKey("username") as! String
txtPassword.text = res.valueForKey("password") as! String
//for res in results {
// print(res)
}else{
print("Incorrect username and password")
}
}
Can anyone please advise my the best way forward? - I just need to retrieve the saved core data and check if it matches.
Here is my Core Data model:
look into below code
func CheckForUserNameAndPasswordMatch (userName : String, password : String) ->Bool
{
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var managedObjectContext = appDelegate.managedObjectContext
var predicate = NSPredicate (format:"userName = %#" ,userName)
var fetchRequest = NSFetchRequest ( entityName: "UserEntity")
fetchRequest.predicate = predicate
var error : NSError? = nil
var fetchRecult = managedObjectContext?.executeFetchRequest(fetchRequest, error: &error)
if fetchRecult?.count>0
{
var objectEntity : UserEntity = fetchRecult?.first as! UserEntity
if objectEntity.userName == userName && objectEntity.password == password
{
return true // Entered Username & password matched
}
else
{
return false //Wrong password/username
}
}
else
{
return false
}
}
Moreover it would not be good to save password in device if you are working on any enterprise product.
import UIKit
import CoreData
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var txt_username: UITextField!
#IBOutlet var txt_password: UITextField!
var result = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func Log_in(_ sender: Any)
{
if txt_username.text == "" && txt_password.text == ""
{
let alert = UIAlertController(title: "Information", message: "Please enter all the fields", preferredStyle: .alert)
let ok = UIAlertAction(title: "Ok", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alert.addAction(ok)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
else
{
self.CheckForUserNameAndPasswordMatch(username : txt_username.text! as String, password : txt_password.text! as String)
}
}
func CheckForUserNameAndPasswordMatch( username: String, password : String)
{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
let fetchrequest = NSFetchRequest<NSFetchRequestResult>(entityName: "LoginDetails")
let predicate = NSPredicate(format: "username = %#", username)
fetchrequest.predicate = predicate
do
{
result = try context.fetch(fetchrequest) as NSArray
if result.count>0
{
let objectentity = result.firstObject as! LoginDetails
if objectentity.username == username && objectentity.password == password
{
print("Login Succesfully")
}
else
{
print("Wrong username or password !!!")
}
}
}
catch
{
let fetch_error = error as NSError
print("error", fetch_error.localizedDescription)
}
}
}
Registration page
==================>
import UIKit
import CoreData
class RegistrationPage: UIViewController, UITextFieldDelegate {
#IBOutlet var txt_user: UITextField!
#IBOutlet var txt_mailid: UITextField!
#IBOutlet var txt_pwd: UITextField!
#IBOutlet var txt_cpwd: UITextField!
#IBOutlet var txt_phone: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func register(_ sender: Any)
{
if txt_user.text == "" || txt_mailid.text == "" || txt_pwd.text == "" || txt_cpwd.text == "" || txt_phone.text == ""
{
let alert = UIAlertController(title: "Information", message: "Its Mandatort to enter all the fields", preferredStyle: .alert)
let ok = UIAlertAction(title: "Ok", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alert.addAction(ok)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
else if (txt_pwd.text != txt_cpwd.text)
{
let alert = UIAlertController(title: "Information", message: "Password does not match", preferredStyle: .alert
)
let ok = UIAlertAction(title: "Ok", style: .default, handler: nil)
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alert.addAction(ok)
alert.addAction(cancel)
self.present(alert, animated: true, completion: nil)
}
else
{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
let new_user = NSEntityDescription.insertNewObject(forEntityName: "LoginDetails", into: context)
new_user.setValue(txt_user.text, forKey: "username")
new_user.setValue(txt_mailid.text, forKey: "mailid")
new_user.setValue(txt_pwd.text, forKey: "password")
new_user.setValue(txt_phone.text, forKey: "phone")
do
{
try context.save()
print("Registered Sucessfully")
}
catch
{
let Fetcherror = error as NSError
print("error", Fetcherror.localizedDescription)
}
}
self.navigationController?.popViewController(animated: true)
}
}
Is username unique as per database constraint? Then, you will never get more than one result from the fetch.
If you use
if let user = results.first where
user.pass == (passField.text ?? "") {
// login
}
else {
// no login
}
you'd be better of.
Also, do not set the field's from the db; check if they are equal.
Also, please realize that such a sign-up will be valid only on a per-app-installation basis.
For production security, store only hashes of passwords.
It is very simple to make a user login system using core data
First you have to create a project and include core data in it. Then you have to add to the .xcdatamodeld file an entity with some attributes.
Here is a picture of how does the file looks like:
CoreData.xcdatamodeld File
Here is the example code:
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newUser = NSEntityDescription.insertNewObject(forEntityName: "Users", into: context)
newUser.setValue("Joe", forKey: "username")
newUser.setValue("JoeTheLazy", forKey: "password")
newUser.setValue(48, forKey: "age")
do {
try context.save()
print("saved")
} catch {
print ( "Some Error has been Detected")
}
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let reusutls = try context.fetch(request)
if reusutls.count > 0 {
for r in reusutls as! [NSManagedObject]
{
if let username = r.value(forKey: "username") as? String
{print(username)}
}
}
else {print("Cannot fetch results")
}
}
catch {
print("error")
}
}
#IBOutlet weak var usrName: UITextField!
#IBOutlet weak var passWord: UITextField!
#IBOutlet weak var showList: UILabel!
#IBOutlet weak var errorText: UILabel!
#IBAction func tryLogin(_ sender: UIButton) {
let x = usrName.text
let y = passWord.text
if (x! == "" || y! == "")
{
print ("I am here")
errorText.text = "user name or password empty "
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.predicate = NSPredicate(format: "username = %#", usrName.text!)
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
let passwordFromData = data.value(forKey: "password") as! String
if y! == passwordFromData
{
errorText.text = " You have been Granted Access!"
}
}
}catch {
print("Failed")
}
}
#IBAction func ShowData(_ sender: UIButton) {
var listTprint = ""
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let reusutls = try context.fetch(request)
if reusutls.count > 0 {
for r in reusutls as! [NSManagedObject]
{
if let username = r.value(forKey: "username") as? String
{listTprint.append(username)
listTprint.append(" ")
let password = r.value(forKey: "password") as? String
listTprint.append(password!)
listTprint.append(" ")
}
}
}
else
{print("Cannot fetch results")}
}
catch {
print("Error")
}
showList.text! = listTprint
}
Coredata save fetch update delete
==================================>
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var my_table: UITableView!
var playerdata = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool)
{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
let fetch_data = NSFetchRequest<NSManagedObject>(entityName: "PlayerDetails")
do
{
self.playerdata = try context.fetch(fetch_data as! NSFetchRequest<NSFetchRequestResult>) as! NSMutableArray
}
catch let error as NSError
{
print(error.localizedDescription)
}
self.my_table.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return playerdata.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = my_table.dequeueReusableCell(withIdentifier: "hari") as! TableViewCell123
let playerdetails = self.playerdata[indexPath.row]
cell.playername.text = (playerdetails as AnyObject) .value(forKey: "player_name")as? String
cell.playerid.text = (playerdetails as AnyObject) .value(forKey: "player_id")as? String
cell.playerteam.text = (playerdetails as AnyObject) .value(forKey: "player_team")as? String
cell.playerimage.image = UIImage(data: ((playerdetails as AnyObject) .value(forKey: "player_img")as? Data)!)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
self.performSegue(withIdentifier: "datapass", sender: self)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)
{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
if(editingStyle == .delete)
{
let user = self.playerdata[indexPath.row] as! NSManagedObject
context.delete(user)
do
{
try context.save()
self.playerdata.removeObject(at: indexPath.row)
my_table.deleteRows(at: [indexPath], with: .fade)
}
catch let error as NSError
{
print("error",error.localizedDescription)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "datapass"
{
let vc2 = segue.destination as! ViewController2
let index = my_table.indexPathForSelectedRow
let data = self.playerdata[(index?.row)!]
vc2.dataupdate = data as! NSManagedObject
}
}
}
VIEWCONTROLLER - 2
===================>
import UIKit
import CoreData
class ViewController2: UIViewController
{
#IBOutlet var txt_playername: UITextField!
#IBOutlet var txt_playerid: UITextField!
#IBOutlet var txt_playerteam: UITextField!
#IBOutlet var img_playerimage: UIImageView!
var dataupdate = NSManagedObject()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if (dataupdate != nil)
{
txt_playername.text = dataupdate.value(forKey: "player_name")as? String
txt_playerid.text = dataupdate.value(forKey: "player_id")as? String
txt_playerteam.text = dataupdate.value(forKey: "player_team")as? String
img_playerimage.image = UIImage(data: dataupdate.value(forKey: "player_img") as! Data)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func save_update(_ sender: Any)
{
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
if (dataupdate != nil)
{
dataupdate.setValue(self.txt_playername.text, forKey: "player_name")
dataupdate.setValue(self.txt_playerid.text, forKey: "player_id")
dataupdate.setValue(self.txt_playerteam.text, forKey: "player_team")
let img_data = UIImageJPEGRepresentation(self.img_playerimage.image!, 1.0)
dataupdate.setValue(img_data, forKey: "player_img")
}
else
{
let newplayer = NSEntityDescription.insertNewObject(forEntityName: "PlayerDetails", into: context)
newplayer.setValue(self.txt_playername.text, forKey: "player_name")
newplayer.setValue(self.txt_playerid.text, forKey: "player_id")
newplayer.setValue(self.txt_playerteam.text, forKey: "player_team")
let img_data = UIImageJPEGRepresentation(self.img_playerimage.image!, 1.0)
newplayer.setValue(img_data, forKey: "player_img")
}
do
{
try context.save()
}
catch let error as NSError
{
print(error.localizedDescription)
}
self.dismiss(animated: true, completion: nil)
}
}

App Crashes on Buy Subscription when first time launched

I'm working on this subscription system for my app,it took a few days.But as I'm working more on it,it makes more problems.
Sometimes it happens that the app crashes when clicking on buy subscription.
Also I'm having the problem of not knowing when to stop the Please wait.... alert.I need to place the code in:
case .Purchasing:
self.alert_show()
break
But I don't know where to end it,I need to know the information when is the alert from iTunes loaded than to stop the Please wait.... alert.
The biggest problem right now that I'm facing is the crashing sometimes when i click on the Buy Button.
The crashing happens when first time launching the app,and clicking one the Buy Subscription.
Here is the code for the Buy Subscription:
#IBAction func buy_sub(sender: AnyObject) {
let payment:SKPayment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
Here is the error that I'm getting.
fatal error: unexpectedly found nil while unwrapping an Optional value..
I would like to share with you my source code of the subscription.If you have any advices what to add,or to correct or to correct this problems that i have it would be great.
Here is the full source code of the Subscription View:
class SubscriptionViewController: UIViewController ,SKPaymentTransactionObserver, SKProductsRequestDelegate {
//var productID = ""
var product: SKProduct!
#IBOutlet var buy_trial_button: UIButton!
override func viewDidAppear(animated: Bool) {
if(SKPaymentQueue.canMakePayments()) {
} else {
buy_trial_button.enabled = false
message_alert("Please enable IAPS to continue(Credit card information required in your iTunes account).")
}
//validateReceipt()
let keystore = NSUbiquitousKeyValueStore.defaultStore()
if keystore.objectForKey("expiration_date") != nil{
let expiration: AnyObject? = keystore.objectForKey("expiration_date")
let today = NSDate()
let expiredate = expiration as! NSDate
print("expiredate is %#",expiredate,today)
// var date1 = NSDate()
// var date2 = NSDate()
if(today.compare(expiredate) == NSComparisonResult.OrderedDescending){
print("today is later than expiredate")
validateReceipt()
print("Validating")
}else if(today.compare(expiredate) == NSComparisonResult.OrderedAscending){
print("today is earlier than expiredate")
self.performSegueWithIdentifier("subscriptionPassed", sender: self)
}
}else{
print("First time launch")
}
}
override func viewDidLoad() {
super.viewDidLoad()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
self.getProductInfo()
//SKPaymentQueue.defaultQueue().addTransactionObserver(self)
//self.getProductInfo()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillDisappear(animated: Bool) {
}
#IBAction func private_policy(sender: AnyObject) {
let openLink = NSURL(string : "http://arsutech.com/private_policy.php")
UIApplication.sharedApplication().openURL(openLink!)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "subscriptionPassed")
{
}
}
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse){
let products = response.products
if products.count != 0
{
product = products[0] as SKProduct
print(product.localizedTitle + "\n" + product.localizedDescription)
}
}
func getProductInfo(){
if (SKPaymentQueue.canMakePayments()){
let productID:NSSet = NSSet(object: "com.sxxxxxxxxxxxxxxxxx")
let request:SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
}
}
#IBAction func buy_sub(sender: AnyObject) {
let payment:SKPayment = SKPayment(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)
}
#IBAction func buy_pro(sender: AnyObject) {
let openLink = NSURL(string : "https://itunes.apple.com/us/app/home-workouts-exercises-mma/id1060747118?mt=8")
UIApplication.sharedApplication().openURL(openLink!)
}
#IBAction func exit(sender: AnyObject) {
exit(0)
}
func validateReceipt(){
alert_show()
let mainBundle = NSBundle.mainBundle() as NSBundle;
let receiptUrl = mainBundle.appStoreReceiptURL;
let isPresent = receiptUrl?.checkResourceIsReachableAndReturnError(NSErrorPointer());
if(isPresent == true){
let data = NSData(contentsOfURL: receiptUrl! );
// Create the JSON object that describes the request
let requestContents = NSMutableDictionary();
//let encodeddata = data!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions());
let encodeddata = data!.base64EncodedString();
//print("encodeddata = \(encodeddata)");
requestContents.setObject(encodeddata, forKey: "receipt-data");
requestContents.setObject("c40f23af1aa44e159aezzzzzzzzzzzzzz", forKey: "password");
var requestData : NSData?
do{
requestData = try NSJSONSerialization.dataWithJSONObject(requestContents, options: NSJSONWritingOptions());
}catch{
// NSLog("Error in json data creation at verifyPaymentReceipt");
}
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let file = "\(documentsPath)/requestData"
if(NSFileManager.defaultManager().createFileAtPath(file, contents: data, attributes: nil)){
NSLog("File %# ",file);
}
else{
//NSLog("error File %# ",file);
}
if(requestData != nil){
//let strRequestData = NSString(data: requestData!, encoding: NSUTF8StringEncoding);
//print(" strRequestData = \(strRequestData)");
// Create a POST request with the receipt data.
//https://buy.itunes.apple.com/verifyReceipt
//https://sandbox.itunes.apple.com/verifyReceipt
let storeURL = NSURL(string: "https://sandbox.itunes.apple.com/verifyReceipt");
let storeRequest = NSMutableURLRequest(URL: storeURL!);
storeRequest.HTTPMethod = "POST";
storeRequest.HTTPBody = requestData;
// Make a connection to the iTunes Store on a background queue.
let queue = NSOperationQueue();
NSURLConnection.sendAsynchronousRequest(storeRequest, queue: queue, completionHandler: { (response : NSURLResponse?, data : NSData?, error : NSError?) -> Void in
if(error != nil){
//Handle Error
}
else{
let d = NSString(data: data!, encoding: NSUTF8StringEncoding);
// NSLog("DATA:%#", d!);
let dataA = d!.dataUsingEncoding(NSUTF8StringEncoding)
var jsonResponseInternal: NSMutableDictionary?
do{
jsonResponseInternal = try NSJSONSerialization.JSONObjectWithData(dataA!,options: NSJSONReadingOptions.AllowFragments) as? NSMutableDictionary;
//print(jsonResponseInternal);
}catch{
// NSLog("Parsing issue : verifyPaymentReceipt");
}
var jsonResponse: NSMutableDictionary?
do{
jsonResponse = try NSJSONSerialization.JSONObjectWithData(data!,
options: NSJSONReadingOptions.AllowFragments) as? NSMutableDictionary;
//print(jsonResponse);
}catch{
// NSLog("Parsing issue : verifyPaymentReceipt");
}
if(jsonResponse != nil){
if(jsonResponse != nil){
//NSLog("Expiration Date: %#", jsonResponse!);
//print("Passed")
/*
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "Purchase")
NSUserDefaults.standardUserDefaults().synchronize()
*/
//self.performSegueWithIdentifier("subscriptionPassed", sender: self)
if jsonResponse!["status"] as? Int == 0 {
//print("Sucessfully returned internal receipt data")
if let receiptInfo: NSArray = jsonResponse!["latest_receipt_info"] as? NSArray {
let lastReceipt = receiptInfo.lastObject as! NSDictionary
var trial_period: Bool = false
// Get last receipt
//print("LAST RECEIPT INFORMATION \n",lastReceipt)
print("Last from internal memory",lastReceipt["original_transaction_id"])
//var is_trial = lastReceipt["is_trial_period"] as! Bool
//var date_bought =
//var date_expires =
// Format date
//print(is_trial)
// Format date
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
// Get Expiry date as NSDate
let subscriptionExpirationDate: NSDate = formatter.dateFromString(lastReceipt["expires_date"] as! String) as NSDate!
print("\n - DATE SUBSCRIPTION EXPIRES = \(subscriptionExpirationDate)")
let currentDateTime = NSDate()
print(currentDateTime)
if var is_trial:Bool = false{
if(lastReceipt["is_trial_period"] as? String == "Optional(\"true\")"){
is_trial = true
trial_period = is_trial
}else if(lastReceipt["is_trial_period"] as? String == "Optional(\"false\")"){
is_trial = false
trial_period = is_trial
}
}
if (subscriptionExpirationDate.compare(currentDateTime) == NSComparisonResult.OrderedDescending) {
self.alrt_close()
print("Pass");
print("The trial period is \(trial_period)")
let keystore = NSUbiquitousKeyValueStore.defaultStore()
keystore.setObject(subscriptionExpirationDate,forKey:"expiration_date")
keystore.synchronize()
self.performSegueWithIdentifier("subscriptionPassed", sender: self)
} else if (subscriptionExpirationDate.compare(currentDateTime) == NSComparisonResult.OrderedAscending) {
print("Not Pass");
print("Subscription expired")
self.alrt_close()
//self.message_alert("Subscription expired")
}
}
}
}
}
}
});
}
}
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction:AnyObject in transactions {
if let trans:SKPaymentTransaction = transaction as? SKPaymentTransaction{
switch trans.transactionState {
case .Purchasing:
//self.alrt_close()
break
case .Deferred:
self.alert_show()
break
case .Purchased:
alrt_close()
self.validateReceipt()
//self.setExpirationDate()
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
//dismissViewControllerAnimated(false, completion: nil)
break
case .Failed:
SKPaymentQueue.defaultQueue().finishTransaction(transaction as! SKPaymentTransaction)
print("Not called Expired")
message_alert("Error while purchasing!")
break
case .Restored:
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
print("Restored")
break
default:
break
}
}
}
}
//Alrt
func message_alert(let message_A:String){
let alert = UIAlertController(title: "", message: "\(message_A)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
func alert_show(){
let alert = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .Alert)
alert.view.tintColor = UIColor.blackColor()
let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(10, 5, 50, 50)) as UIActivityIndicatorView
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
presentViewController(alert, animated: true, completion: nil)
}
func alrt_close(){
self.dismissViewControllerAnimated(false, completion: nil)
}
}

swift reading array on interval shows index out of range

I have a page that show messages from a database. The message is getting loaded as it should but when i try to reload it to show the new messages after a interval of one minute i get the message out of range. It looks like the array is empty for some reason. I have read so many of the solutions but non of them explain what is happening in my code.
This is the complete code.
import UIKit
import Foundation
class LeftSideViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var answerPMTapped: UIButton!
#IBOutlet weak var senderProfileImage: UIImageView!
#IBOutlet weak var profileImageView: UIImageView!
#IBOutlet weak var BodyMessage: UITextView!
#IBOutlet weak var TitleMessage: UILabel!
#IBOutlet weak var totalKm: UILabel!
#IBOutlet weak var ranking: UILabel!
#IBOutlet weak var totalCollected: UILabel!
#IBOutlet weak var profileName: UILabel!
#IBOutlet weak var euroSign: UILabel!
var MessageId = [String]()
var MessageSender = [String]()
var MessageReceiver = [String]()
var MessageBody = [String]()
var MessageTime = [String]()
var MessageDate = [String]()
var MessageStatus = [String]()
var MessageTitle = [String]()
var SenderUsername = [String]()
var ReplyMessageId = [String]()
var T_message_Title:String!
var menuItems:[String] = ["Home","Profiel", "Goede Doelen", "Berichten", "Verstuur bericht", "Instellingen","Uitloggen"];
var menuImage: [String] = ["home", "profile", "charity", "message", "reply", "settings", "logout"]
var urlString = String()
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = true
load_message()
}
override func viewDidLoad() {
super.viewDidLoad()
get_user_data()
get_my_message_list()
/* if (TitleMessage != nil){
var title_convert = MessageTitle[1]
var message_convert = MessageBody[1]
TitleMessage.text = title_convert
BodyMessage.text = message_convert
} else {
BodyMessage.text = "Er zijn geen berichten op dit moment."
} */
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var userEmail = prefs.valueForKey("USERNAME") as! String
let newUsername = userEmail.stringByReplacingOccurrencesOfString(".", withString: "")
let NewUserName = newUsername.stringByReplacingOccurrencesOfString("#", withString: "")
let imgString = NewUserName
var urlString = "xxxxxxxx/profile/image/\(imgString).jpg"
euroSign.hidden = true
if (totalCollected != nil) {
euroSign.hidden = false
}
self.profileImageView.layer.cornerRadius = self.profileImageView.frame.size.width / 2;
self.profileImageView.clipsToBounds = true;
load_profile_image(urlString)
var reload_messages = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("message_Reloader"), userInfo: nil, repeats: true)
}
func message_Reloader(){
self.MessageId.removeAll()
self.MessageSender.removeAll()
self.MessageReceiver.removeAll()
self.MessageBody.removeAll()
self.MessageTime.removeAll()
self.MessageDate.removeAll()
self.MessageStatus.removeAll()
self.MessageTitle.removeAll()
self.SenderUsername.removeAll()
self.ReplyMessageId.removeAll()
get_my_message_list()
load_message()
}
func load_profile_image(urlString: String){
var imgURL: NSURL = NSURL(string: urlString)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!, data: NSData!,error: NSError!) -> Void in
if error == nil {
self.profileImageView.image = UIImage(data: data)
println(imgURL)
}
})
}
func get_user_data(){
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var userEmail = prefs.valueForKey("USERNAME") as! String
let url = NSURL(string:"xxxxxx/fetch-user-profile.php")
let cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
var request = NSMutableURLRequest(URL: url!, cachePolicy: cachePolicy, timeoutInterval: 2.0)
request.HTTPMethod = "POST"
// set Content-Type in HTTP header
let boundaryConstant = "----------V2ymHFg03esomerandomstuffhbqgZCaKO6jy";
let contentType = "multipart/form-data; boundary=" + boundaryConstant
NSURLProtocol.setProperty(contentType, forKey: "Content-Type", inRequest: request)
// set data
var dataString = "username=\(userEmail)"
let requestBodyData = (dataString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
request.HTTPBody = requestBodyData
// set content length
//NSURLProtocol.setProperty(requestBodyData.length, forKey: "Content-Length", inRequest: request)
var response: NSURLResponse? = nil
var error: NSError? = nil
let dataReply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
if(dataReply != nil){
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
var results = NSJSONSerialization.JSONObjectWithData(dataReply!, options: nil, error: &error) as! NSDictionary
NSLog("PostData: %#",dataReply!);
NSLog("ResultData: %#",results);
var jsonOutput = JSON(data: dataReply!)
totalKm.text = jsonOutput["total_km"].stringValue
totalCollected.text = jsonOutput["collected"].stringValue
ranking.text = jsonOutput["rank"].stringValue
profileName.text = jsonOutput["username"].stringValue
} else {
println( "Fetching data failed.")
}
} else {
println( "Fetching data failed.")
}
}
func load_message(){
println("\(MessageBody[0])")
var messagebody = MessageBody[0]
var messagetitle = MessageTitle[0]
var messagesender = MessageSender[0]
let newUsername = messagesender.stringByReplacingOccurrencesOfString(".", withString: "")
let NewUserName = newUsername.stringByReplacingOccurrencesOfString("#", withString: "")
let imgString = NewUserName
var urlString = "xxxxxxxxx/profile/image/\(imgString).jpg"
self.senderProfileImage.layer.cornerRadius = self.senderProfileImage.frame.size.width / 2;
self.senderProfileImage.clipsToBounds = true;
var imgURL: NSURL = NSURL(string: urlString)!
let request: NSURLRequest = NSURLRequest(URL: imgURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!, data: NSData!,error: NSError!) -> Void in
if error == nil {
self.senderProfileImage.image = UIImage(data: data)
println(imgURL)
}
})
if (messagetitle.isEmpty){
BodyMessage.text = "Er zijn geen berichten op dit moment."
}
else {
TitleMessage.text = messagetitle
BodyMessage.text = messagebody
}
}
#IBAction func answerPM(sender: AnyObject) {
var messageid = MessageId[0]
var messagesender = MessageSender[0]
var messagereceiver = MessageReceiver[0]
var senderusername = SenderUsername[0]
var replymessageid = ReplyMessageId[0]
// send over the orignal message so we can use that info to show the message again when they click the back button
var messagedate = MessageDate[0]
var messagebody = MessageBody[0]
var messagetitle = MessageTitle[0]
var messagetime = MessageTime[0]
var messagesendeR = MessageSender[0]
var centerViewController = self.storyboard?.instantiateViewControllerWithIdentifier("answerMessage") as! answerMessageView
centerViewController.MessageId2 = messageid
centerViewController.MessageSender2 = messagesender
centerViewController.MessageReceiver2 = messagereceiver
centerViewController.SenderUsername2 = senderusername
centerViewController.ReplyMessageId2 = replymessageid
println("sender username: \(senderusername) reply message id: \(replymessageid)")
centerViewController.A_messagedate = messagedate
centerViewController.A_messagebody = messagebody
centerViewController.A_messagetitle = messagetitle
centerViewController.A_messagetime = messagetime
centerViewController.A_messagesendeR = messagesendeR
var centerNavController = UINavigationController(rootViewController: centerViewController)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = centerNavController
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
}
#IBAction func viewAllMessages(sender: AnyObject) {
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("messagesList") as! MessagesView
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
}
#IBAction func markMGSRead(sender: AnyObject) {
}
func get_my_message_list(){
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var receiverEmail = prefs.valueForKey("USERNAME") as! String
println("userEmail: \(receiverEmail)")
let request = NSMutableURLRequest(URL: NSURL(string: "xxxxxxxxxx/user/fetchmymessages.php")!)
//let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
request.HTTPMethod = "POST"
var postData = "receiveremail=\(receiverEmail)"
request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
NSLog("data: \(request)")
var task = NSURLSession.sharedSession().dataTaskWithRequest(request) {(data, response, innerError) in
NSLog("response: \(response)")
let json = JSON(data: data)
if json != nil {
let mysocialArray = json.arrayValue
NSLog("\(json)")
dispatch_async(dispatch_get_main_queue(), {
for mysociallist in mysocialArray
{
let messageId = mysociallist["message_id"].stringValue
let sender = mysociallist["sender"].stringValue
let receiver = mysociallist["receiver"].stringValue
let messageBody = mysociallist["message"].stringValue
let time = mysociallist["time"].stringValue
let date = mysociallist["date"].stringValue
let messageStatus = mysociallist["message_read"].stringValue
let messagesubject = mysociallist["message_title"].stringValue
let senderusername = mysociallist["sender_username"].stringValue
let replymessageid = mysociallist["reply_message_id"].stringValue
println( "message id: \(messageId)" )
println( "message sender: \(sender)" )
self.MessageId.append(messageId)
self.MessageSender.append(sender)
self.MessageReceiver.append(receiver)
self.MessageBody.append(messageBody)
self.MessageTime.append(time)
self.MessageDate.append(date)
self.MessageStatus.append(messageStatus)
self.MessageTitle.append(messagesubject)
self.SenderUsername.append(senderusername)
self.ReplyMessageId.append(replymessageid)
}
})
}else {
var alertView:UIAlertView = UIAlertView()
alertView.title = "Berichten ophalen mislukt"
alertView.message = "Er is een fout opgetreden, daardoor kunnen de berichten niet tonen."
alertView.delegate = self
alertView.addButtonWithTitle("OK")
alertView.show()
}
}
task.resume()
}// end of get my message list
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return menuItems.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var mycell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! MyCustomTableViewCell
mycell.menuItemLabel?.text = menuItems[indexPath.row]
mycell.menuItemImage?.image = UIImage(named: menuImage[indexPath.row])
return mycell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
switch(indexPath.row)
{
case 0:
var centerViewController = self.storyboard?.instantiateViewControllerWithIdentifier("memberArea") as! userOverview
var centerNavController = UINavigationController(rootViewController: centerViewController)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = centerNavController
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 1:
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("userProfile") as! userProfile
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 2:
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("userProfile") as! userProfile
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 3:
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("messagesList") as! MessagesView
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 4:
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("answerMessage") as! answerMessageView
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 5:
var userProfiles = self.storyboard?.instantiateViewControllerWithIdentifier("answerMessage") as! answerMessageView
var userProfileNav = UINavigationController(rootViewController: userProfiles)
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.centerContainer!.centerViewController = userProfileNav
appDelegate.centerContainer!.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)
break;
case 6:
let appDomain = NSBundle.mainBundle().bundleIdentifier
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain!)
self.performSegueWithIdentifier("loggin_out", sender: self)
break;
default:
println("\(menuItems[indexPath.row]) is selected");
}
}
}
this is the full code but the part that is giving the error is when the following is being called,
override func viewDidLoad() {
super.viewDidLoad()
var reload_messages = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("message_Reloader"), userInfo: nil, repeats: true)
}
func message_Reloader(){
self.MessageId.removeAll()
self.MessageSender.removeAll()
self.MessageReceiver.removeAll()
self.MessageBody.removeAll()
self.MessageTime.removeAll()
self.MessageDate.removeAll()
self.MessageStatus.removeAll()
self.MessageTitle.removeAll()
self.SenderUsername.removeAll()
self.ReplyMessageId.removeAll()
get_my_message_list()
load_message()
}
i have left out a little part of viewdidload to make it not too long.
I am not a pro so i can really use some help here to figure out how to called the function and store it in the array so i can show the new message.
Hope some one can give me some code examples or can point me into the right direction, i am really stuck here and it keeps crashing my app.
Thanks
You have a race condition in your code: get_my_message_list() method is asynchronous, so load_message() can be called before get_my_message_list() is completed. In load_message() you're trying to access array members at index 0:
...
var messagebody = MessageBody[0]
var messagetitle = MessageTitle[0]
...
And that's the problem: those arrays can be empty (if get_my_message_list() still haven't updated them).

Resources