Present tab bar controller based on a set of conditions - uiviewcontroller

In, one of my multiple UIViewControllers, I have a sign in button that takes you to a tab bar scene. The viewcontrollers shown in the tab bar scene depends on the type of account selected. In another scene, there's a button which updates it's titlelabel based on type of account. Here is what I have done.
class SIgn_In: UIViewController {
let tabbar = UITabBarController()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func didTapSignIn(_ sender: Any) {
guard let vc = storyboard?.instantiateViewController(identifier: "vc") as? AccountViewController else{return}
let firstVc = First()
let secondVc = Second()
let thirdVc = Third()
if vc.text == "accountType1" {
tabbar.setViewControllers([firstVc,secondVc], animated: false)
} else if vc.text == "accounttype2" {
tabbar.setViewControllers([thirdVc,firstVc,secondVc], animated: false)
}
present(tabbar,animated: true)
}
In the accountViewController, I have this code.
class AccountViewController: UIViewController {
#IBOutlet weak var button: UIButton!
public var accountType:String = ""
override func viewDidLoad() {
super.viewDidLoad()
accountType = button.currentTitle!
}
But I'm not quite getting what I expected, what am I missing? Please help

Related

Why my Collectionview cells are not showing when i move from that viewcontroller in swift?

I am able to parse JSON and adding cells in Collectionview.. but if i move from this Viewcontroller and coming to viewcontroller then collectionview is not showing.. but added data in JSON
code for adding collectionview and JSON parsing:
class ImageItemModel{
var title: String?
var profileImage: UIImage?
var pic_id: Double?
init(title: String?, imgTitle: UIImage?, pic_id: Double?) {
self.title = title
self.profileImage = imgTitle
self.pic_id = pic_id
}
}
class EditProfileImageViewController: UIViewController {
#IBOutlet weak var titleTextfield: UITextField!
private var imageProfile : UIImage?
private var imagePicker : EasyImagePicker?
#IBOutlet weak var collectionView: UICollectionView!
var arrImageItems = [ImageItemModel]()
#IBAction func imgtitleSaveBtn(_ sender: Any) {
postServiceCall()
}
fileprivate func postServiceCall(){
if titleTextfield.text?.trim() == ""{
return self.view.makeToast("please add service title")
}
let parameters = ["image_title" : titleTextfield.text?.trim() ?? ""]
APIReqeustManager.sharedInstance.uploadMultipartFormData(param: parameters, url: CommonUrl.edit_profile_images, image: imageProfile, fileName: "image", vc: self, isHeaderNeeded: true) {(responseData) in
print("edit profile result \(responseData)")
if let result = responseData.dict?["result"] as? NSDictionary{
let success = result["status"] as? [String : Any]
let message = success?["message"] as? String
if message == "Success"{
let image = result["image"] as? [String : Any]
let picId = image?["id"]
self.arrImageItems.append(ImageItemModel(title: self.titleTextfield.text, imgTitle: self.imageProfile, pic_id: picId as! Double))
self.collectionView.reloadData()
}
else{
self.view.makeToast(CommonMessages.somethingWentWrong)
}
}
}
}
extension EditProfileImageViewController : UICollectionViewDelegate,UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrImageItems.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
cell.imgView.image = arrImageItems[indexPath.item].profileImage
cell.lblTitle.text = arrImageItems[indexPath.row].title
cell.deleteButton.tag = indexPath.row
cell.deleteButton.addTarget(self, action: #selector(deleteService(sender:)), for: UIControl.Event.touchUpInside)
return cell
}
}
with the above code i am able to add collectionview cells and able to store data in JSON but.. if i move from this viewcontroller and coming back to this viewcontroller then collectionview is not showing, why? whats wrong? please do help me with code.. i got stuck here from long time.
There are couple of issues that you should fix for this to work properly. I will give you reason for each.-
You are loading your data with the postServiceCall() method which has an asynchronous network call. There is no way to know when the controller is done fetching the data to the arrImageItems array. So, you should have used a completion handler.
Now you are updating the collectionView within the asynchronous dataTask which a background thread. BIG mistake. Whenever you have any UI related task, you do it under the main thread. So, you could refactor the APIReqeustManager.sharedInstance.uploadMultipartFormData() part of your code following way-
APIReqeustManager.sharedInstance.uploadMultipartFormData(param: parameters, url: CommonUrl.edit_profile_images, image: imageProfile, fileName: "image", vc: self, isHeaderNeeded: true) {(responseData) in
print("edit profile result \(responseData)")
if let result = responseData.dict?["result"] as? NSDictionary{
let success = result["status"] as? [String : Any]
let message = success?["message"] as? String
if message == "Success"{
let image = result["image"] as? [String : Any]
let picId = image?["id"]
self.arrImageItems.append(ImageItemModel(title: self.titleTextfield.text, imgTitle: self.imageProfile, pic_id: picId as! Double))
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
else{
DispatchQueue.main.async {
self.view.makeToast(CommonMessages.somethingWentWrong)
}
}
}
}
Now unless you want your viewcontroller to show the data in your collectionView only when the action, imgtitleSaveBtn(_:) is triggered, you need to get data everytime, when your view controller appeared on screen. To fix that issue, you should get the data in the viewWillAppear(_:) method like-
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
postServiceCall()
}
Now, the above two edits should fix your issue depending on how you want to load your collectionview but your code is breaking quite some coding standards. Coding standards sounds like a clique but trust me you want to follow those if you ever want to update the capability of your app without breaking it. The following is just some hints-
Whenever you are in an asynchronous call, you should consider calling a completion handler for returning your data.
Should look into your methods, you are dangerously breaking the single responsibility principal.
In more than one place, you force unwrapped. Bad idea. You need your system to have a fail safe rather than just crashing on you.
Update 2:
Updates with a design pattern:
Compartmentalise your code in MVC pattern. Put the ImageItemModel class in its own file. See the image below to understand the design-
Customize the collectionViewCell within the ImageCollectionViewCell. Let's assume your custom cell has only the outlets.
class ImageCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imgView: UIImageView!
#IBOutlet weak var lblTitle: UILabel!
#IBOutlet weak var deleteButton: UIButton!{
didSet{
deleteButton.addTarget(self, action: #selector(deleteService(_:)), for: .touchUpInside)
}
}
// however this could easily be done with IBAction
#objc func deleteService(_ sender: UIButton){
}
}
Update the postServiceCall and return the data to your controller with a completion handler, means when the postServiceCall is done executing, an array of images or an empty array should be returned based on success or failure. Then the controller can decide what to do with the data, in your case update UI. with couple of refactoring, here is the updated controller code.
import UIKit
import EasyImagePicker
class EditProfileImageViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!{ //for troubleshooting
didSet{ //purpose, do it from code
collectionView.delegate = self
collectionView.dataSource = self
}
}
#IBOutlet weak var titleTextfield: UITextField!
private var imageProfile : UIImage?
private var imagePicker : EasyImagePicker? // you never used this var.
var arrImageItems = [ImageItemModel]()
// any time a view controller appears on screen this method gets called.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
reloadMyCollectionView()
}
#IBAction func imgtitleSaveBtn(_ sender: Any) {
reloadMyCollectionView()
}
fileprivate func reloadMyCollectionView(){
postServiceCall{ images in
self.arrImageItems = images
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
// look into escaping closures to understand, why you need it here
fileprivate func postServiceCall(completed: #escaping(_ images: [ImageItemModel])->Void){
// don't force unwrap, get optional values safely with guard let
guard let titleText = titleTextfield.text, titleText == "" else{
return
}
let parameters = ["image_title" : titleText]
APIReqeustManager.sharedInstance.uploadMultipartFormData(param: parameters, url: CommonUrl.edit_profile_images, image: imageProfile, fileName: "image", vc: self, isHeaderNeeded: true) {(responseData) in
print("edit profile result \(responseData)")
//capture the data in local scope and return that array with a completion handler
var imageItems = []
if let result = responseData.dict?["result"] as? NSDictionary{
let success = result["status"] as? [String : Any]
let message = success?["message"] as? String
if message == "Success"{
let image = result["image"] as? [String : Any]
let picId = image?["id"]
imageItems.append(ImageItemModel(title: self.titleTextfield.text, imgTitle: self.imageProfile, pic_id: picId as! Double))
}
}
self.completed(imageItems) // if there is nothing in result,
//imageItems will be empty, otherwise it will have imageItemModel data
}
}
}
extension EditProfileImageViewController : UICollectionViewDelegate,UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrImageItems.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as? ImageCollectionViewCell{
cell.imgView.image = arrImageItems[indexPath.item].profileImage
cell.lblTitle.text = arrImageItems[indexPath.row].title
cell.deleteButton.tag = indexPath.row
//cell.deleteButton.addTarget(self, action: #selector(deleteService(sender:)), for: UIControl.Event.touchUpInside)
return cell
}
else{
return UICollectionViewCell()
}
}
}
Notice postServiceCall and cellForItemAt methods.
If you still have the same issue then you need to show your whole code to get any further help.

Share JSON Data in TabBarController to view controllers

I am using a tabbarcontroller to show 3 xib's. I would like to decode JSON data in the UITabBarController subclass, and then share the data with the view controllers (as I understand that is the preferred way to do this). I had already successfully accomplished this individually in each view controller, where the same JSON data was getting decoded separately 3 times, but I am now trying to make the process more efficient by only dealing with JSON once.
I am currently getting the following error
"Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffee7ab7d98)".
Below is the code I am currently using. I'm mostly only including the code for the first view controller, but it is the same for the others
Here is one of the view controllers. Any help would be appreciated, thank you!
class FirstCollectionViewController: UIViewController {
var tbvc = CustomTabBar()
var statisticsData = [Model]()
let firstCellIdentifier = "FirstCellIdentifier"
#IBOutlet weak var FirstCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
FirstCollectionView.delegate = self
FirstCollectionView.dataSource = self
FirstCollectionView.register(UINib(nibName: "FirstCollectionViewCell", bundle: nil),forCellWithReuseIdentifier: firstCellIdentifier)
}
}
Here is the subclasses UITabBarController
import UIKit
class CustomTabBar: UITabBarController {
let website = "https:......."
var statisticsData = [Model]()
override func viewDidLoad() {
super.viewDidLoad()
let firstTab = FirstCollectionViewController(nibName: "FirstCollectionViewController", bundle: nil)
let secondTab = SecondCollectionViewController(nibName: "SecondCollectionViewController", bundle: nil)
let thirdTab = ThirdCollectionViewController(nibName: "ThirdCollectionViewController", bundle: nil)
viewControllers = [firstTab, secondTab, thirdTab]
downloadJSON(website: website) {
firstTab.statisticsData = self.statisticsData
secondTab.statisticsData = self.statisticsData
thirdTab.statisticsData = self.statisticsData
firstTab.FirstCollectionView.reloadData()
secondTab.SecondCollectionView.reloadData()
thirdTab.ThirdCollectionView.reloadData()
}
}
func downloadJSON(website:String, completed:#escaping ()->()){
guard let qurl = URL(string: website) else { return }
URLSession.shared.dataTask(with: qurl) { (data, response, error) in
if error == nil {
do{
self.statisticsData = try JSONDecoder().decode([Model].self, from: data!)
DispatchQueue.main.async{
completed()
}
} catch {
print("JSON Error")
}}
}.resume()
}
}
Once the data is loaded, you should assign the data to the viewControllers that are added in the tabBarController's Child list as below,
downloadJSON(website: website) {
firstTab.statisticsData = self.statisticsData
secondTab.statisticsData = self.statisticsData
thirdTab.statisticsData = self.statisticsData
firstTab.FirstCollectionView.reloadData()
secondTab.SecondCollectionView.reloadData()
thirdTab.ThirdCollectionView.reloadData()
}
You can also remove the below lines from viewDidLoad of FirstCollectionViewController, SecondCollectionViewController and ThirdCollectionViewController
tbvc = tabBarController as! CustomTabBar
statisticsData = tbvc.statisticsData

Add Login page from mysql database to swift

I'm trying to implement a website's login database to a swift app but I can't seem to find how to do so, all of the things I find online don't really help. The website stores the login data in a mySQL database and I want to implement that into my app.
Here is my code:
import UIKit
class SignInViewController: UIViewController,UITextFieldDelegate {
#IBOutlet var UsernameTextField: UITextField!
#IBOutlet var PasswordTextField: UITextField!
#IBOutlet var LogInButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
navigationController?.view.backgroundColor = UIColor.clear
// Remove Autocorrection Type
UsernameTextField.autocorrectionType = .no
PasswordTextField.autocorrectionType = .no
PasswordTextField.textContentType = UITextContentType("")
//Next button takes user to the next textfield
UsernameTextField.delegate = self
PasswordTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func LogInButtonTapped(_ sender: Any) {
// `READ VALUES FROM TEXTFIELDS
let username = UsernameTextField.text
let password = PasswordTextField.text
// CHECK IF BOTH FIELDS ARE EMPTY
if (username?.isEmpty)! && (password?.isEmpty)! {
// DISPLAY ALERT MESSAGE HERE
print("User name \(String(describing: username)) or password \(String(describing: password)) is empty")
displayMessage(userMessage: "Both fields are required to fill in")
return
} else if (password?.isEmpty)! {
displayMessage(userMessage: "You did not enter a passwords")
return
} else if (username?.isEmpty)! {
displayMessage(userMessage: "You did not enter a username")
return
}
// CREATE ACTIVITY INDICATOR
let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
// POSITION ACTIVITY INDICATOR IN CENTER OF THE VIEW
myActivityIndicator.center = view.center
// START ACTIVITY INDICATOR
myActivityIndicator.startAnimating()
view.addSubview(myActivityIndicator)
}
func displayMessage(userMessage:String) -> Void {
DispatchQueue.main.async
{
let alertController = UIAlertController(title: "Alert", message: userMessage, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
// Code in this block will trigger when OK button tapped.
DispatchQueue.main.async
{
self.dismiss(animated: true, completion: nil)
}
}
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion:nil)
}
}
//Remove keyboard on tap of screen and Go to next textfield everytime user taps on next
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == UsernameTextField{
PasswordTextField.becomeFirstResponder()
} else if textField == PasswordTextField {
self.view.endEditing(true)
}
return true
}
func removeActivityIndicator(activityIndicator: UIActivityIndicatorView)
{
DispatchQueue.main.async
{
activityIndicator.stopAnimating()
activityIndicator.removeFromSuperview()
}
}
}
How do I add the login information from the mysql database into the application? My objective here is to create an app for the website where I can use the same username and password as the one of the website.
You would have to create an API service for the app to send the username and password and your backend validate if the login is valid.
Look into REST/JSON services.

swift: how to pass JSON to secondViewController

I want to pass the JSON data to MainMenuPageViewController.
MainMenuPageViewController UILabel(UsernameLabel)
Thank you
Picture1:
let jsonUserId: String = json["return"] as! String
if (jsonUserId != "0") {
print("username and password correct")
dispatch_async(dispatch_get_main_queue(), {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("MainMenuPageViewController")
self.showViewController(vc, sender: self)
//pass the jsonUserId to MainMenuPageViewController
//MainMenuPageViewController has UILabel(UserIdLabel)
})
}
If I input wrong username and password, system will run to line 57 but the alert will error, when I input long String(a,A,#,etc.). However, if I input shot String(shing, herry,123,etc.) app can display the alert message.
Also, if input the space bar and (!##$%^&*()_+). it will error.
Can you help me to fix this error? Thank you.
Just declare variable in MainMenuPageViewController like
class MainMenuPageViewController: UIViewController {
var UserIdLabel = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
and for pass data
let jsonUserId: String = json["return"] as! String
if (jsonUserId != "0") {
print("username and password correct")
dispatch_async(dispatch_get_main_queue(), {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if let vc = storyboard.instantiateViewControllerWithIdentifier("MainMenuPageViewController") as? MainMenuPageViewController {
vc.UserIdLabel = jsonUserId
self.showViewController(vc, sender: self)
}
})
}
You should create a property in the MainMenuPageViewController to store the user id and then in viewDidLoad set the UsernameLabel text to the stored property.
var userID:String! //define this in the MainMenuPageViewController
Then after you create the vc set the userID property to the jsonUserID
if let vc = storyboard.instantiateViewControllerWithIdentifier("MainMenuPageViewController") as? MainMenuPageViewController {
vc.userID = jsonUserId
self.showViewController(vc, sender: self)
} else {
printf("The VC is not of the right type")
}
override func viewDidLoad() {
super.viewDidLoad()
UsernameLabel.text = userID
}

unexpectedly found nil while unwrapping an Optional value for my UITextField

I'm having trouble passing the JSON values (I'm reading successfully) into my textfield on the next viewcontroller because of this unwrapping error, stating my text field is nil.
I'm very stuck. Here's my class that reads the JSON:
class DoOAuth
{
func doOAuthFitbit() -> String{
var name = ""
let oauthswift = OAuth1Swift(
consumerKey: "eabf603efe9e45168d057b60b03f8e94",
consumerSecret: "46b4dfa8c9d59666769e03f887d531a8",
requestTokenUrl: "https://api.fitbit.com/oauth/request_token",
authorizeUrl: "https://www.fitbit.com/oauth/authorize?display=touch",
accessTokenUrl: "https://api.fitbit.com/oauth/access_token")
oauthswift.authorizeWithCallbackURL( NSURL(string: "fitbit://oauth")!,
success:{
credential, response in
let vc: ViewController = ViewController()
let user: OAuthSwiftClient = OAuthSwiftClient(consumerKey: oauthswift.consumer_key, consumerSecret: oauthswift.consumer_secret, accessToken: credential.oauth_token, accessTokenSecret: credential.oauth_token_secret)
let object:[String : AnyObject] = ["oauth_token": credential.oauth_token, "oauth_token_secret" : credential.oauth_token_secret]
user.get("https://api.fitbit.com/1/user/-/profile.json", parameters: object,
success: {
(data: NSData, response: NSHTTPURLResponse) -> Void in
let jsonValues = JSON(data: data, options: NSJSONReadingOptions.AllowFragments, error: nil)
println(jsonValues)
/*public var dictionary: [Swift.String: JSON]?
{
switch self
{
case .Dictionary(let d):
var jsonObject: [Swift.String: JSON] = [:]
for(k,v) in d
{
jsonObject[k] = JSON.wrap(v)
}
return jsonObject
default:
return nil
}
}*/
for(key, subJson) in jsonValues
{
if let nm = subJson["fullName"].string
{
println("\(nm)")
name = nm
}
}
/*for(index: String, subJson: JSON) in jsonValues
{
let name = subJson.dictionary?["fullName"]?.string
println("\(name!)")
//vc.nm.text = name!
main.acceptJson(name!)
}*/
},
failure: {
(error:NSError!) -> Void in
println(error.localizedDescription)
println("error")
})
},
failure: {
(error:NSError!) -> Void in
println(error.localizedDescription)
})
return name
}
}
I call a function that is supposed to receive the JSON strings (acceptJson) located in the next view controller:
class mainMenu: UIViewController
{
var oauthfitbit: DoOAuth = DoOAuth()
var name = ""
//let vc: ViewController = ViewController()
#IBOutlet weak var lbl: UILabel!
#IBOutlet weak var nameField: UITextField!{
didSet{
nameField.text = name
}
}
override func viewWillAppear(animated: Bool)
{
//name = oauthfitbit.doOAuthFitbit()
//self.nameField.text = "Working"
//self.nameField.text = name
}
func acceptJson(info: String!)
{
println("\(info)")
self.nameField.text = info
//name = info
}
}
I get the excepting thrown on the setting nameField.text line stating nameField is nil. How do I get the textfield to store the JSON string?
And here's the initial View Controller:
class ViewController: UIViewController {
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.
}
#IBOutlet weak var nm: UITextField!
//let main: mainMenu = mainMenu()
var name = ""
#IBAction func connectPressed(sender: UIButton)
{
var oauthFitbit: DoOAuth = DoOAuth()
name = oauthFitbit.doOAuthFitbit()
self.performSegueWithIdentifier("loginSuccess", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "loginSuccess")
{
let controller = segue.destinationViewController as! mainMenu
controller.name = name
//vc.nameField.text = "Hello"
}
}
}
How did you create your textfield? Was it through Interface Builder? There have been plenty of times when I've run into these type of problems when using Interface Builder and IBOutlets.
The first step is to make sure your text field is connected to your view controller from the .xib file correctly. Delete the connection and reconnect by control (command?) dragging from IB to your view controller code.
If you're not using IB and still having problems, post the code where you create the textfield. You have to set your view controller as the text field delegate if you're creating it programmatically, I believe. It's been awhile since I've done it that way.
Let us know!
The easiest way to get the new view controller the value of nm is in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "YourIdentifier" {
let controller = segue.destinationViewController as! mainMenu
controller.name = name
}
}
So, to get this to work, you will need to add a name instance variable (var name = "") to your first view controller, and change main.acceptJson(nm) to name = nm.
Once name is set in your first view controller, you can segue to the second view controller.
In the second view controller, you can change your text field outlet to this:
#IBOutlet weak var nameField: UITextField! {
didSet {
nameField.text = name
}
}
The didSet is a property observer. You can't set the nameField text field directly from the first view controller's prepareForSegue because the text field isn't set up yet when prepareForSegue is called in the first view controller. That's why you're storing it in an instance variable. Then, because of the didSet, your text field's text property will be set as soon as it comes into existence.
UPDATE:
The following is in a class of its own. Let's call that class DoOAuth (looks like that's what you called it):
class DoOAuth {
func doOAuthFitbit() -> String { // Now it's returning a string
var name = "" // Create local variable to return
let oauthswift = OAuth1Swift(
consumerKey: "eabf603efe9e45168d057b60b03f8e94",
consumerSecret: "46b4dfa8c9d59666769e03f887d531a8",
requestTokenUrl: "https://api.fitbit.com/oauth/request_token",
authorizeUrl: "https://www.fitbit.com/oauth/authorize?display=touch",
accessTokenUrl: "https://api.fitbit.com/oauth/access_token")
oauthswift.authorizeWithCallbackURL( NSURL(string: "fitbit://oauth")!,
success:{
credential, response in
//let vc: ViewController = ViewController() // Get rid of this
let user: OAuthSwiftClient = OAuthSwiftClient(consumerKey: oauthswift.consumer_key, consumerSecret: oauthswift.consumer_secret, accessToken: credential.oauth_token, accessTokenSecret: credential.oauth_token_secret)
let object:[String : AnyObject] = ["oauth_token": credential.oauth_token, "oauth_token_secret" : credential.oauth_token_secret]
user.get("https://api.fitbit.com/1/user/-/profile.json", parameters: object,
success: {
(data: NSData, response: NSHTTPURLResponse) -> Void in
let jsonValues = JSON(data: data, options: NSJSONReadingOptions.AllowFragments, error: nil)
println(jsonValues)
/*public var dictionary: [Swift.String: JSON]?
{
switch self
{
case .Dictionary(let d):
var jsonObject: [Swift.String: JSON] = [:]
for(k,v) in d
{
jsonObject[k] = JSON.wrap(v)
}
return jsonObject
default:
return nil
}
}*/
for(key, subJson) in jsonValues
{
if let nm = subJson["fullName"].string
{
println("\(nm)")
name = nm // Store 'nm' in local variable declared above
}
}
}
return name
} // end doOAuthFitbit()
} // end class
Now change your connectPressed() method in ViewController to this:
#IBAction func connectPressed(sender: UIButton)
{
var oauthFitbit: DoOAuth = DoOAuth()
name = oauthFitbit.doOAuthFitbit() // doOAuthFitbit() now returns a String
self.performSegueWithIdentifier("loginSuccess", sender: nil)
}
Now it should work.