Add elements to search history? - ios

I have a model - Movies.
and two controllers - first for search movie by title, second - for display result with poster, title and year.
Now i need to create some history search on my third controller
(searchHistoryController - TableView) where displayed all movies, and when i tapped on cell with movie's title show movie info.
How I can build it?
I tried create array in my model. And write resutl in it, but each time when i use search it rewrite array, not add new element.
Maybe use realm
Need some help:)
Movie.swift
import Foundation
import UIKit
import Alamofire
import AlamofireImage
protocol MovieDelegate {
func updateMovieInfo()
}
class Movie {
private let omdbUrl = "http://www.omdbapi.com/?"
var title: String?
var filmYear: String?
var poster: String?
var delegete: MovieDelegate!
var historyMovie = [Movie]()
func getMovieInfo(title: String, completion: #escaping ()->()){
let params = ["t": title]
Alamofire.request(omdbUrl, method: .get, parameters: params).validate(statusCode: 200..<300).validate(contentType: ["application/json"]).responseJSON { (response) in
switch response.result {
case .success(let JSON):
let response = JSON as! NSDictionary
let status = response["Response"] as! String
if status == "True" {
self.title = (response["Title"] as! String)
self.filmYear = (response["Year"] as! String)
self.poster = (response["Year"] as! String)
// self.delegete.updateMovieInfo()
completion()
} else {
self.title = (response["Error"] as! String)
completion()
}
case .failure(let error):
print (error)
}
}
}
}
SearchVC
import UIKit
class SearchViewController: UIViewController {
var movie = Movie()
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
#IBOutlet weak var searchTextField: UITextField!
#IBOutlet weak var searchButton: UIButton!
#IBAction func searchButtonTapped(_ sender: UIButton) {
activityIndicator.startAnimating()
DispatchQueue.main.async {
self.movie.getMovieInfo(title: self.searchTextField.text!, completion: {
self.activityIndicator.stopAnimating()
self.performSegue(withIdentifier: "movieInfo", sender: self)
})
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let secondVC = segue.destination as! DetailInfoViewController
secondVC.movieTitle = movie.title!
}
}
DetailVC
class DetailInfoViewController: UIViewController, MovieDelegate {
#IBAction func showHistory(_ sender: UIButton) {
performSegue(withIdentifier: "showHistory", sender: self)
}
#IBOutlet weak var posterImageView: UIImageView!
#IBOutlet weak var filmNameLabel: UILabel!
#IBOutlet weak var filmYearLabel: UILabel!
var movie = Movie()
var movieTitle = ""
override func viewDidLoad() {
super.viewDidLoad()
self.movie.getMovieInfo(title: movieTitle ) {
self.updateMovieInfo()
}
self.movie.delegete = self
}
func updateMovieInfo() {
getPoster(link: movie.poster)
filmNameLabel.text = movie.title
filmYearLabel.text = movie.filmYear
}
func getPoster(link: String?) {
if link != nil {
guard let url = URL(string: link!) else { return }
DispatchQueue.global().async {
if let data = try? Data(contentsOf: url) {
DispatchQueue.main.async {
self.posterImageView.image = UIImage(data: data)
}
}
} } else {
self.posterImageView.image = #imageLiteral(resourceName: "Image")
}
}
}

First of all, movieHistory should not be part of your Movie class, but part of your SearchViewController class.
Second of all, unless you want to persist your data, you don't need Realm for this.
Just save the movies in SearchViewController into an array once the search button has been tapped and send it to your other view controller in the segue. Like so
#IBAction func searchButtonTapped(_ sender: UIButton) {
activityIndicator.startAnimating()
DispatchQueue.main.async {
self.movie.getMovieInfo(title: self.searchTextField.text!, completion: {
self.activityIndicator.stopAnimating()
movieHistory.append(movie)
self.performSegue(withIdentifier: "movieInfo", sender: movieHistory)
})
}
}
Also, modify prepare(for segue:...) like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let secondVC = segue.destination as! DetailInfoViewController
secondVC.movieTitle = movie.title!
secondVC.movieHistory = movieHistory
}
In detailVC override prepare(for segue:...) as well and send movieHistory to searchHistoryController the same way it is done in the previous VC.

Related

Swift - Accessing implicitly unwrapped variable gives a nil error

I'm following a tutorial on CoreData and I've been following it exactly, yet when they run the app, everything works and saves correctly, yet I get a nil error. The tutorial is a few years old, so I'm not sure if something has been udpated in the way CoreData works. It's an app to save goals.
Here's the first view controller where you enter the text of the goal and if it is short or long term:
import UIKit
class CreateGoalViewController: UIViewController, UITextViewDelegate {
#IBOutlet weak var goalTextView: UITextView!
#IBOutlet weak var shortTermButton: UIButton!
#IBOutlet weak var longTermButton: UIButton!
#IBOutlet weak var nextButton: UIButton!
var userGoalType: GoalType = .shortTerm
override func viewDidLoad() {
super.viewDidLoad()
nextButton.bindToKeyboard()
shortTermButton.setSelectedColor()
longTermButton.setDeselectedColor()
print("\(userGoalType)")
goalTextView.delegate = self
}
#IBAction func nextButtonPressed(_ sender: Any) {
if goalTextView.text != "" && goalTextView.text != "What is your goal?" {
guard let finishVC = storyboard?.instantiateViewController(withIdentifier: "FinishVC") as? FinishGoalViewController else {return}
finishVC.initData(description: goalTextView.text!, type: userGoalType)
print("\(finishVC.goalType.rawValue) after next button pressed")
performSegue(withIdentifier: "goToFinish", sender: self)
}
}
#IBAction func longTermButtonPressed(_ sender: Any) {
userGoalType = .longTerm
longTermButton.setSelectedColor()
shortTermButton.setDeselectedColor()
print("\(userGoalType)")
}
#IBAction func shortTermButtonPressed(_ sender: Any) {
userGoalType = .shortTerm
shortTermButton.setSelectedColor()
longTermButton.setDeselectedColor()
print("\(userGoalType)")
}
#IBAction func backButtonPressed(_ sender: Any) {
dismiss(animated: true)
}
func textViewDidBeginEditing(_ textView: UITextView) {
goalTextView.text = ""
goalTextView.textColor = UIColor(ciColor: .black)
}
}
And here's the following view controller where you set the number of times you want to do that goal where the CoreData functions are:
import UIKit
import CoreData
class FinishGoalViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var createButton: UIButton!
#IBOutlet weak var pointsTextField: UITextField!
var goalDescription: String!
var goalType: GoalType!
func initData(description: String, type: GoalType) {
self.goalDescription = description
self.goalType = type
}
override func viewDidLoad() {
super.viewDidLoad()
createButton.bindToKeyboard()
pointsTextField.delegate = self
}
#IBAction func createGoalPressed(_ sender: Any) {
if pointsTextField.text != ""{
self.save { finished in
if finished {
dismiss(animated: true)
}
}
}
}
#IBAction func backButtonPressed(_ sender: Any) {
dismiss(animated: true)
}
func save(completion: (_ finished: Bool) -> ()) {
guard let managedContext = appDelegate?.persistentContainer.viewContext else {return}
let goal = Goal(context: managedContext)
goal.goalDescription = goalDescription
goal.goalType = goalType.rawValue
goal.goalCompletionValue = Int32(pointsTextField.text!)!
goal.goalProgress = Int32(0)
do{
try managedContext.save()
print("successfully saved data")
completion(true)
}catch{
debugPrint("Could not save: \(error.localizedDescription)")
completion(false)
}
}
}
I'm getting a nil error in the save function with the goalType.rawValue turning up nil. The goal type is set up in an enum file:
import Foundation
enum GoalType: String {
case longTerm = "Long Term"
case shortTerm = "Short Term"
}
I'm not sure why there's an error. Because in the CreateGoalViewController, I print the goalType.rawValue from the following view controller and it comes up with the correct string, either short or long-term. But when FinishGoalViewController loads, it is all of a sudden nil.
You are initiating and configuring your FinishGoalViewController in nextButtonPressed but you never use it. performSegue(withIdentifier: "goToFinish", sender: self) will create and push a new instance of FinishGoalViewController.
The most simple aproach would be to push your allready configured controller from your curent Controller. Remove performSegue(... and use.
self.navigationController?.pushViewController(finishVC, animated: true)
If you still want to use the segue, remove everything from the nextButtonPressed function, leaving just the performSegue(... line. After that add this function to your CreateGoalViewController controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToFinish" {
if let finishVC = segue.destination as? FinishGoalViewController {
// configure finshVC here
}
}
}

How can I pass dictionary from one view controller class to another?SWIFT

I am trying to make a list of users and their passwords in one view controller, save that information in a dictionary, and send that dictionary to another view controller which asks the user to input their username/password combination to authorize the log in. (the key is the username and the value is the password). Is there a way I can send the dictionary from SecondVC to the FirstVC?
First View Controller
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var Username: UITextField!
#IBOutlet weak var Verification: UILabel!
#IBOutlet weak var Password: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
Username.delegate = self
Password.delegate = self
}
var usersDict = [String : String]()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let des = segue.destination as? AccountViewController {
des.usersDict = usersDict
}
}
#IBAction func Authorization(_ sender: Any) {
for ( key , value ) in usersDict{
let v = key.count
var start = 0
if start <= v{
if Username.text == key{
if Password.text == value{
Verification.text = "Looks Good"
}
}
else{
start += 1
}
}
else{
Verification.text = "Yikes"
}
}
}
}
Second View Controller
class AccountViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var CreateUsername: UITextField!
#IBOutlet weak var CreatePassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
CreateUsername.delegate = self
CreatePassword.delegate = self
// Do any additional setup after loading the view.
}
var usersDict = [ String : String ]()
#IBAction func MakeANewAccount(_ sender: Any) {
usersDict[CreateUsername.text!] = CreatePassword.text!
}
}
I have made there dictionary, but it will only send in the beginning and won't update after creating the original account. (dictionary it is sending is empty)
With a segue add this method inside ViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let des = segue.destination as? AccountViewController {
des.usersDict = yourDicHere
}
}
Here's a general pattern for making a controller work with data from some object it creates, in this case a second controller.
Try applying it to your situation and let me know if you run into problems.
protocol Processor {
func process(_ dict: [String : String])
}
class FirstController: UIViewController, Processor {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let controller = segue.destination as? SecondController {
controller.delegate = self
} else {
print("Unexpected view controller \(segue.destination)")
}
}
func process(_ dict: [String : String]) {
}
}
class SecondController: UIViewController {
var delegate: Processor?
func someWork() {
if let processor = delegate {
processor.process(["Name" : "Pwd"])
} else {
print("Delegate not assigned")
}
}
}

How to pass Item from initial (one time) first time view controller to main view controller and save that data using core data

I have been working on this issue for two days now and sadly I cannot figure out the issue to my problem. I'm trying to take one item from my initial one time view controller and send that to my main view controller where it will be saved within the main view controller and will appear upon that controller when reloading the app.
Here is my app delegate code for the "first time" view controller
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if UserDefaults.standard.bool(forKey: "firstTimer") {
let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
let mainView = storyBoard.instantiateViewController(withIdentifier: "MainViewControllerID")
let nav = UINavigationController(rootViewController: mainView)
nav.navigationBar.isHidden = true
self.window?.rootViewController = nav
}
return true
}
containers and saveContext are default
import UIKit
import CoreData
class FirstTimeViewController: UIViewController {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
private var appDelegate = UIApplication.shared.delegate as! AppDelegate
private var player = [Player]()
#IBOutlet weak var nameTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// This View Controller will only be used once upon the first time the app is being used.
// MARK: Make func that prepares for segue on initial opening of app
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toMainViewController" {
let mainViewController = segue.destination as! UINavigationController
let destination = mainViewController.topViewController as! MainViewController
if let newPlayer = self.nameTextField.text{
destination.name.name = newPlayer
destination.playerData.name = newPlayer
saveItems()
}
}
}
#IBAction func continueButtonPressed(_ sender: UIStoryboardSegue) {
UserDefaults.standard.set(true, forKey: "firstTimer")
let mainPlayer = PlayerData()
let player1 = Player(entity: Player.entity(), insertInto: context)
player1.name = mainPlayer.name
performSegue(withIdentifier: "toMainViewController", sender: self)
saveItems()
}
func saveItems() {
do {
try context.save()
print("File Successfully saved!")
}catch {
print("Error saving Context \(error)")
}
}
// MARK: Function to Save and Load data??
/*
// 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.destination.
// Pass the selected object to the new view controller.
}
*/
func loadItems() {
let request = Player.fetchRequest() as NSFetchRequest<Player>
do {
player = try context.fetch(request)
print("Info loaded")
} catch {
print("Error fetching data from context \(error)")
}
}
}
MainViewController being sent the information. I only want to send one item and save it to that main view controller.
import UIKit
import Foundation
import CoreData
class MainViewController: UIViewController {
//set up model object, buttons, and labels
// let player: Player!
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
private var appDelegate = UIApplication.shared.delegate as! AppDelegate
// lazy var nameText = Player(context: context)
// var playerInfo = [Player]()
lazy var player = [Player]()
let playerData = PlayerData()
var name = ""
#IBOutlet weak var playerName: UILabel!
#IBOutlet weak var currentLevel: UILabel!
#IBOutlet weak var xpCounter: UILabel!
#IBOutlet weak var playerProfileImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// loadItems()
// name = playerData.name
if let nameOfPlayer = name.name {
print("This is what we see: \(nameOfPlayer)")
playerName.text = nameOfPlayer
}
appDelegate.saveContext()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// loadView()
}
#IBAction func menuButtonPressed(_ sender: Any) {
}
func loadItems() {
let request = Player.fetchRequest() as NSFetchRequest<Player>
do {
player = try context.fetch(request)
print("Info loaded")
} catch {
print("Error fetching data from context \(error)")
}
}
// MARK : Add Name to Main View
// MARK : Add Xp To Main View
// MARK : Add UI Image to profile image view
// MARK: (Optional) Create a 'Choose a task button to segue to the task tab'
// MARK: Program the Progress Bar to update on xp gained and reset on level up
// MARK: Function to Save and Load data??
}
If dataSource code needed I will add upon request.
Thanks!
Code is wrong. You should do more check
This is what I was able to achieve:
import UIKit
import CoreData
class FirstTimeViewController: UIViewController {
private var player = [Player]()
private var appDelegate = UIApplication.shared.delegate as! AppDelegate
private let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
#IBOutlet weak var nameTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// This View Controller will only be used once upon the first time the app is being used.
// MARK: Make func that prepares for segue on initial opening of app
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toMainViewController" {
let entity = NSEntityDescription.entity(forEntityName: "Player", in: context)
let newPlayer = NSManagedObject(entity: entity!, insertInto: context)
if let newUser = self.nameTextField.text{
newPlayer.setValue(newUser, forKey: "name")
print("This is what i got: ", newPlayer)
}
appDelegate.saveContext()
}
}
#IBAction func continueButtonPressed(_ sender: UIStoryboardSegue) {
UserDefaults.standard.set(true, forKey: "firstTimer")
performSegue(withIdentifier: "toMainViewController", sender: self)
}
And for the Main View Controller:
import UIKit
import Foundation
import CoreData
class MainViewController: UIViewController {
//set up model object, buttons, and labels
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
private var appDelegate = UIApplication.shared.delegate as! AppDelegate
lazy var player = [Player]()
#IBOutlet weak var playerName: UILabel!
#IBOutlet weak var currentLevel: UILabel!
#IBOutlet weak var xpCounter: UILabel!
#IBOutlet weak var playerProfileImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
// request.predicate = NSPredicate(format: "name = %#", "noon")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "name") as! String)
self.playerName.text = data.value(forKey: "name") as? String
}
} catch {
print("Failed")
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// loadView()
}
#IBAction func menuButtonPressed(_ sender: Any) {
}

How to transfer data between view controller using segues

I'm trying to pass data using a prepare(for segue:) function but it's showing nil in the second VC. Am I doing anything wrong?
class ViewController: UIViewController {
var first : [String] = []
#IBOutlet weak var passField: UITextField!
#IBOutlet weak var userID: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func login(_ sender: Any) {
let user : String = self.userID.text!
let password : String = self.passField.text!
if user != "" && password != "" {
let postString = ["username":user, “password”: password]
var request = URLRequest(url:URL(string:"http://mydomainhere.com/api/login")!)
request.httpMethod = "POST"
request.httpBody = try! JSONSerialization.data(withJSONObject: postString, options:.prettyPrinted)
let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
print("error=\(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
let firstName = json["first_name"] as? String
let lastName = json["last_name"] as? String
self.first.append(firstName!) //putting into Array
self.performSegue(withIdentifier: "loginSegue", sender: self)
}
} catch {
print(error)
}
}
}
}
// data transfer to another controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "loginSegue" {
let secondController = segue.destination as? SecondVC
secondController?.name = first //passing to next VC //* here having the issue its not passing the data to next VC
print(first) // here first is printing perfectly
}
}
}
// second View Controller
class SecondVC: UIViewController {
var menu_vc : MenuViewController!
var name : [String]? // passing to this Array
override func viewDidLoad() {
super.viewDidLoad()
print(name) // here printing nil
}
}
As suggested by #Sweeper, it could very well be that your destination view controller is embedded in a UINavigationViewController, hence your segue.destination is in fact a UINavigationViewController, not a SecondVC.
You can try this code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var destinationViewController = segue.destination
if let navigationController = destinationViewController as? UINavigationController {
destinationViewController = navigationController.visibleViewController ?? destinationViewController
}
if let secondController = destinationViewController as? SecondVC {
secondController?.name = first
}
}
Of course the first four lines of code could be refactored in an appropriate function (even better if in an extension of UIViewController).
If that solves the problem, you can watch cs193p Stanford iOS course for further details.
In particular watch https://www.youtube.com/watch?v=HQrXM2zUPvY&index=6&list=PLPA-ayBrweUz32NSgNZdl0_QISw-f12Ai starting from the 30:20 mark.
Everything seems perfect with the below snippet
var first : [String] = []
#IBAction func btnTapped(_ sender: Any) {
let firstName = "iOS Geek"
self.first.append(firstName)
self.performSegue(withIdentifier: "MovetoSecVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MovetoSecVC"{
let secVC = segue.destination as! SecondVC
secVC.name = first
print(first) // it'll print here ["iOS Geek"]
}
}
// Your Second View Controller
class SecondVC: UIViewController {
var menu_vc : MenuViewController!
var name : [String]? // passing to this Array
override func viewDidLoad() {
super.viewDidLoad()
print(name!) // it'll print here ["iOS Geek"]
}
}

How to Update UITableView with data passed from another ViewController?

I am trying to populate a UITableView with data passed to the ViewController from LoginViewController after the user logs in.
The current process is:
ViewController loads first, if user is not logged in LoginViewController pops up over the top. User logs in, details are fetched from the database (userDetails and communities). LoginViewController is then dismissed and ViewController is again visible.
The communities variable is being populated and values transferred from LoginViewController to ViewController.
I believe my problem is func tableView is run before the data is fetched from the user logging in.
print ("test 1: ",communities) just prints [],[],[],[]
However print ("test 2: ",communities) prints the correct values.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UsernameSentDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var receiveUsername: UILabel!
#IBOutlet weak var userEmailText: UILabel!
var userEmail: String?
var communities = [String]()
#IBOutlet weak var communitiesTableView: UITableView!
#IBAction func unwindToHome(_ segue: UIStoryboardSegue) {
}
//recieves email address from delegate from LoginViewController
func userLoggedIn(data: String) {
userEmailText.text = data
}
override func viewDidLoad() {
super.viewDidLoad()
self.communitiesTableView.delegate = self
self.communitiesTableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print ("test 1: ",communities) //not printing value
return self.communities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let title = self.communities[indexPath.row]
let cell = UITableViewCell()
cell.textLabel?.text = title
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "loginView" {
let loginViewController: LoginViewController = segue.destination as! LoginViewController
loginViewController.delegate = self
}
if segue.identifier == "createCommunitySegue" {
let createCommunityController: CreateNewCommunity = segue.destination as! CreateNewCommunity
createCommunityController.myEmail = userEmailText.text
}
}
override func viewDidAppear(_ animated: Bool)
{
print ("test 2: ",communities) //prints values correctly
let isUserLoggedIn = UserDefaults.bool(UserDefaults.standard)(forKey: "isUserLoggedIn");
if(!isUserLoggedIn)
{
self.performSegue(withIdentifier: "loginView", sender: self);
}
}
#IBAction func logoutButtonTapped(_ sender: AnyObject) {
UserDefaults.set(UserDefaults.standard)(false, forKey: "isUserLoggedIn");
self.performSegue(withIdentifier: "loginView", sender: self);
}
#IBAction func createCommunityTapped(_ sender: AnyObject) {
}
}
This is the code for CreateCommunityViewController:
import UIKit
class CreateNewCommunity: UIViewController {
#IBOutlet weak var communityNameTextField: UITextField!
#IBOutlet weak var passwordTextField: UILabel!
#IBOutlet weak var emailLabel: UILabel!
var myEmail: String?
#IBAction func cancelButtonPapped(_ sender: AnyObject) {
self.performSegue(withIdentifier: "unwindCommunity", sender: self)
}
#IBAction func createCommunityButtonTapped(_ sender: AnyObject) {
let communityName = communityNameTextField.text;
if (communityName!.isEmpty){
displayMyAlertMessage(userMessage: "You must name your Community");
return;
}else{
func generateRandomStringWithLength(length: Int) -> String {
var randomString = ""
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
for _ in 1...length {
let randomIndex = Int(arc4random_uniform(UInt32(letters.characters.count)))
let a = letters.index(letters.startIndex, offsetBy: randomIndex)
randomString += String(letters[a])
}
return randomString
}
let communityCode = generateRandomStringWithLength(length: 6)
passwordTextField.text = communityCode
let myUrl = URL(string: "http://www.quasisquest.uk/KeepScore/createCommunity.php?");
var request = URLRequest(url:myUrl!);
request.httpMethod = "POST";
let postString = "communityname=\(communityName!)&code=\(communityCode)&email=\(myEmail!)";
request.httpBody = postString.data(using: String.Encoding.utf8);
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async
{
if (try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]) != nil {
let myAlert = UIAlertController(title: "Community Registered", message: "Community Code:\(communityCode)", preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default){(action) in
self.dismiss(animated: true, completion: nil)
}
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil)
}
}
}
task.resume()
}
}
}
Try to call reload data in didSet. E.g. var communities = [] { didSet { yourtableview.realoadData()
}
}

Resources