I am currently working on facebook login app.And i am trying to display user cover photo and user profile pic.
But here i was not able to pic the cover, profile photo and not able to populate in my image views.
here my code :
func getFacebookGraphAndSegue(token:String) {
guard let req = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,name, first_name, last_name,id,cover,picture.width(100).height(100)"], tokenString: token, version: nil, httpMethod: "GET") else {
print("could not get Facebook user info")
return
}
req.start(completionHandler: { (connection, result, error) in
if(error == nil) {
print("result \(result)")
guard let userInfo = result as? [String: AnyObject] else {print("bad result");return}
let name = userInfo["name"] as? String ?? ""
// let cover = (userInfo["cover"] as? UIImage!)["source"]{
// var coverUrl = cover as? String
//
// }
self.performSegue(withIdentifier: "loginSegue", sender: userInfo)
}
else {
print("error \(error)")
}
})
}
//--------------------------------------------------------------------------------------------
// MARK: - Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "loginSegue" {
if let vc = segue.destination as? UserViewController {
if let info = sender as? [String: AnyObject] {
let email = info["email"] as? String ?? ""
let name = info["name"] as? String ?? ""
let firstName = info["first_name"] as? String ?? ""
let lastName = info["last_name"] as? String ?? ""
let lbl:String = "\nNAME:\(name)"
print(lbl)
vc.info = lbl
}
}
}
}
the commented line in above function is i tried to get the cover photo as well as profile pic and below i need to display.
In my next screen only i will display user name, profile pic,cover photo :
#IBOutlet weak var labelUserInfo: UILabel!
#IBOutlet weak var coverpageImage: UIImageView!
#IBOutlet weak var profilePicImage: UIImageView!
var info:String = ""
override func viewDidLoad() {
super.viewDidLoad()
self.labelUserInfo.text = info
}
#IBAction func onLogout(_ sender: UIButton) {
//Facebook Logout
print("on Facebook Logout Tapped")
let loginManager = LoginManager()
loginManager.logOut()
self.performSegue(withIdentifier: "logouSegue", sender: nil)
}
please help me out. How can i get the cover , profile pic to display in my screen / image view.
thanks
Related
Hi friends I am just trying to add, update and delete data with api. But whenever I hit add data I need to store the id for deletion and updation purpose. can someone please help me with how to store id while adding in database and I can pass id to next view controller. please let me know just to store id while adding in database that's it
import UIKit
import Alamofire
class ViewController: UIViewController {
var data = NSArray()
var datasnew = NSArray()
#IBOutlet var lastnameText: UITextField!
#IBOutlet var citytext: UITextField!
#IBOutlet var firstnametext: UITextField!
#IBAction func add(_ sender: Any) {
if firstnametext.text == ""{
print("please enter some text")
} else {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController
vc.first = firstnametext.text!
vc.last = lastnameText.text!
vc.city = citytext.text!
vc.id = ""
let parameters: Parameters = [
"fname":"\(firstnametext.text!)",
"lname":"\(lastnameText.text!)",
"city":"\(citytext.text!)"
]
Alamofire.request("http://jewelish.co.in/test/insert.php", method: .post, parameters: parameters).responseJSON { (response) in
if let JSON = response.result.value{
// print("JSON: \(JSON)")
let dict = JSON as! NSDictionary
// print("dict: \(dict)")
}
self.present(vc, animated: true, completion: nil)
}
self.data.addingObjects(from: [datasnew])
}
}
override func viewDidLoad() {
super.viewDidLoad()
Alamofire.request("http://jewelish.co.in/test/get.php", method: .post).responseJSON { (response) in
if let JSON = response.result.value{
// print("JSON: \(JSON)")
let dict = JSON as! NSDictionary
// print(dict)
self.data = dict.value(forKey: "Data")! as! NSArray
let fname = self.data.value(forKey: "fname")
// print(fname)
}
}
}
}
As I understood, you are waiting to navigate to the next screen until you get the response from the server. So after calling API http://jewelish.co.in/test/insert.php you might be getting some response as json or xml, for example, you are getting
{ fnale:"first name",
lname: "last name",
.
.
.,
id={generated from backend developer}
}
so try to add one more key to the response as id which will be generated from the backend developer. and update your #IBAction func add(_ sender: Any) {} function like below.
#IBAction func add(_ sender: Any) {
if firstnametext.text == ""{
print("please enter some text")
} else {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController
vc.first = firstnametext.text!
vc.last = lastnameText.text!
vc.city = citytext.text!
vc.id = ""
let parameters: Parameters = [
"fname":"\(firstnametext.text!)",
"lname":"\(lastnameText.text!)",
"city":"\(citytext.text!)"
]
Alamofire.request("http://jewelish.co.in/test/insert.php", method: .post, parameters: parameters).responseJSON { (response) in
if let JSON = response.result.value{
// print("JSON: \(JSON)")
let dict = JSON as! NSDictionary
vc.id = dict["id"]
// print("dict: \(dict)")
}
self.present(vc, animated: true, completion: nil)
}
self.data.addingObjects(from: [datasnew])
}
}
NOTE: I have checked with your API url, and I can see the following as response, so asked your API developer to give you modified response as mention above.
{
status: 1,
message: "Successfully done"
}
I m having blank data in another view controller, I can pass data between table view controller but I m having a problem to parse data from login method and pass access token or username from JSON?
#IBOutlet weak var username_textfield: UITextField!
#IBOutlet weak var password_textfield: UITextField!
var logindata : [Login] = []
var myResponse : JSON = nil
func getlogin(){
let headers = [
"Content-Type": "application/x-www-form-urlencoded"
]
let parameters = [
"UserName": username_textfield.text! as String,
"Password": password_textfield.text! as String,
"grant_type": "password",
]
// let url = NSURL(string: "http://192.168.100.5:84/Token")!
Alamofire.request("http://192.168.100.5:84/Token", method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case.success(let data):
print("success",data)
let statusCode = (response.response?.statusCode)!
if statusCode == 200{
self.view.makeToast(message: "Welcome !!")
self.performSegue(withIdentifier: "mainview", sender: self)
}else{
self.view.makeToast(message: "Username or password invalid")
}
self.myResponse = JSON(data)
let login = Login(loginJson: self.myResponse)
DispatchQueue.main.async(execute: { () -> Void in
self.performSegue(withIdentifier: "pass_data", sender: login)
})
case.failure(let error):
print("Not Success",error)
}
}
}
passing data to another view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "pass_data" {
if let eventsVC = segue.destination as? MenuDrawerViewController,
let loginData = sender as? Login {
eventsVC.login_details = loginData
}
}
}
i have model class
class Login{
var access_token = String()
var token_type = String()
var expire_in = String()
var username = String()
var masterid = String()
var name = String()
var access = String()
var issued = String()
var expries = String()
init(loginJson:JSON){
self.access_token = loginJson["access_token"].stringValue
self.token_type = loginJson["token_type"].stringValue
self.expire_in = loginJson["expires_in"].stringValue
self.username = loginJson["userName"].stringValue
self.masterid = loginJson["MasterID"].stringValue
self.name = loginJson["Name"].stringValue
self.access = loginJson["Access"].stringValue
self.issued = loginJson[".issued"].stringValue
self.expries = loginJson[".expires"].stringValue
}
}
and in second view controller I have call class like this
class MenuDrawerViewController: UIViewController {
var login_details : Login?
override func viewDidLoad() {
super.viewDidLoad()
titlename_text.text = login_details?.name
// Do any additional setup after loading the view.
}
}
I m a bit confused where I'm getting wrong or I'm doing it in wrong
way, how it can be solved?
i want to pass data through navigation controller and without using navigation controller data is passed so i try this function to pass and it giving me error on "if let detailController" condition
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "dashboard" {
let navController = segue.destination as! UINavigationController
if let detailController = navController.topViewController as! ViewController,
let loginData = sender as? Login {
detailController.login_details = loginData
}
}
}
For loop here is unnecessary because you are not getting array of Login data what you need is to directly use self.myResponse to make object of Login. Also you are performing segue twice with different identifier perform segue to specific identifier with your corresponding destination controller.
Alamofire.request("http://192.168.100.5:84/Token", method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case.success(let data):
print("success",data)
let statusCode = (response.response?.statusCode)!
if statusCode == 200{
self.view.makeToast(message: "Welcome !!")
}else{
self.view.makeToast(message: "Username or password invalid")
}
self.myResponse = JSON(data)
let login = Login(loginJson: self.myResponse)
DispatchQueue.main.async(execute: { () -> Void in
self.performSegue(withIdentifier: "pass_data", sender: login)
})
case.failure(let error):
print("Not Success",error)
}
}
Now make your prepareForSegue like this
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "pass_data" {
if let eventsVC = segue.destination as? MenuDrawerViewController,
let loginData = sender as? Login {
eventsVC.login_details = loginData
}
}
}
I'm new to using the Facebook API, and I'm trying to make a profile page with the user's name, profile picture and cover photo all taken from Facebook. I was able to parse through the JSON data provided and get the name, cover url and picture url, but when I try and set them to IBOutlets that are in another class, it doesn't change anything. The UILabel and UIImageViews remain the same.`
class ViewController: UIViewController, BWWalkthroughViewControllerDelegate, FBSDKLoginButtonDelegate {
var profilePageViewController : profilePage!
var profileVC = profilePage()
override func viewDidLoad() {
super.viewDidLoad()
let stb = UIStoryboard(name: "Main",bundle: nil)
profilePageViewController = stb.instantiateViewController(withIdentifier: "profile") as! profilePage
profileVC = profilePageViewController
}
// MARK: FACEBOOK DELEGATE
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("Logged out of Facebook")
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil{
print(error)
return
}
}
func showFacebookInformation(){
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, picture.type(large),cover"]).start(completionHandler: { (connction, result, error) in
if(error != nil){
print("Failed to start Graph API request", error)
return
}
print(result)
let result = result as! Dictionary<String,Any>
// GETTING COVER PHOTO URL
let cover = result["cover"] as! Dictionary<String,Any>
let coverSource = cover["source"] as! String
// GETTING NAME
let name = result["name"] as! String
// GETTING PROFILE PICTURE
let picture = result["picture"] as! Dictionary<String,Any>
let data = picture["data"] as! Dictionary<String,Any>
let url = data["url"] as! String
print("The profile picture URL is: ",url)
print("The cover photo url is: ",coverSource)
print("The name is: ",name)
DispatchQueue.main.async {
self.profileVC.profilePicture.sd_setImage(with: URL(string:url))
self.profileVC.userName.text = name
}
})
}
#IBAction func logUserIn(){
FBSDKLoginManager().logIn(withReadPermissions: ["public_profile"], from: self) { (result, error) in
if(error != nil){
print("Facebook Login failed: ",error)
return
}
else{
self.profileVC.loadViewIfNeeded()
self.showFacebookInformation()
}
}
}
}
}
I can see that you are trying to set UILabel and UIImageView from the Viewcontroller where you have instantiated rather pass the data to the to profile viewcontroller and set values there in its viewdidload or in viewwillappear methods. It is happening because the layout has not been prepared yet.
I have these JSON data:
{"login":"ET001","email":"email#try.com"}
In Swift 3.0, I created two files which are LoginVC and ViewController.
ViewController can only be accessed after LoginVC verified the credentials. So far I managed to make the login access the ViewController page based on "success" JSON data from database.
But my next goal is to pass the JSON data "[login]" from LoginVC into ViewController.
In ViewController, I created UILabel "loginLbl" to display the JSON value from LoginVC.
How do update my code?
LoginVC.swift
import UIKit
class LoginVC: UIViewController {
#IBOutlet var _login: UITextField!
#IBOutlet var _pass: UITextField!
#IBOutlet var outputLbl: UILabel!
var login: String!
var pass: String!
override func viewDidLoad() {super.viewDidLoad()}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "tocey"{
if let destination = segue.destination as? ViewController {
destination.passedData = self.outputLbl.text
print("Sender value is : \(sender)")
}
}
}
#IBAction func loginData(_ sender: Any) {
login = _login.text
pass = _pass.text
if(login == "" || pass == "") {
return
}
else {
let url = URL(string: "http://localhost/login.php")
let session = URLSession.shared
let request = NSMutableURLRequest(url: url! as URL)
request.httpMethod = "POST"
let paramToLogin = "login=\(login!)&pass=\(pass!)"
request.httpBody = paramToLogin.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
if error != nil {
return
}
else {
do {
if let json = try JSONSerialization.jsonObject(with: data!) as? [String: String] {
DispatchQueue.main.async {
let success = Int(json["success"]!)
let loginvaluefromdb = json["login"]
if(success == 1){
self.outputLbl.text = loginvaluefromdb;
let abc = json["login"]
self.performSegue(withIdentifier: "tocey", sender: abc)
return
}
}
}
}
catch {
}
}
})
task.resume()
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet var loginLbl: UILabel!
var passedData: String!
override func viewDidLoad() {
super.viewDidLoad()
loginLbl.text = passedData
}
}
How to pass it into UILabel loginLbl?
Once you identify that login data is correct in your response you need to push your viewController in navigation controller and take one dictionary in your viewController and assign json to that dictionary.
if let json = try JSONSerialization.jsonObject(with: data!) as? [String: String] {
DispatchQueue.main.async {
let success = Int(json["success"]!)
let loginvaluefromdb = json["login"]
if(success == 1){
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "yourViwController") as! yourViwController
viewController.dictJson = json
self.navigationController?.pushViewController(viewController, animated: true)
}
if(success == 1){
self.outputLbl.text = loginvaluefromdb;
// Here you trigger the segue
self.performSegue(withIdentifier: "goToViewController", sender: loginvaluefromdb)
return
}
You need to pass the data in prepare for segue method :
Here is the editec code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToViewController" {
if let destination = segue.destination as? ViewController {
// Here you will copy tha data you want to pass
destination.passedData = sender as? String
print("Sender Value: \(sender)")
}
}
}
I'm trying to get Facebook's user name and photo in my code. I'm able to do both, but the problem is the segue is called before the data return to me! So when I go to the next screen, the variables are nil! Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - FB Button customization:
if (FBSDKAccessToken.currentAccessToken() == nil){
print("Not logged in")
}
else{
print("This is where you perform a segue.")
fetchProfile()
performSegueWithIdentifier("nextfb", sender: self)
}
}
func fetchProfile() {
print("fetch profile")
let parameters = ["fields": "email, name, picture.type(large)"]
FBSDKGraphRequest(graphPath: "me", parameters: parameters).startWithCompletionHandler { (connection, result, error) -> Void in
if error != nil {
print(error)
return
}
if let name = result["name"] as? String {
self.nome = name
print(name)
print(self.nome)
}
if let email = result["email"] as? String {
self.email = email
print(email)
}
// pega a imagem do usuário:
if let data = result["picture"]?!["data"]
{
if let url = data!["url"] as? String
{
let profilePictureURL = url
let imgURL = NSURL(string: profilePictureURL)
let imageData = NSData(contentsOfURL: imgURL!)
let image = UIImage(data: imageData!)
print(image)
self.foto = image!
}
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "nextfb" {
print("\nO NOME É: \(nome)\n")
let vc = segue.destinationViewController as! HomeViewController
vc.name = self.nome
//vc.photo = self.foto
}
}
The second View Controller prints a nil value for the name AND THEN the first View Controller prints the name and the image! (when I'm already in the second View Controller)
How can I pass those variables via segue properly?? Any help is much appreciated!
You are calling performSegueWithIdentifier("nextfb", sender: self) in the wrong place. You are checking the existence of your access token, and if you aren't logged in, you are invoking the segue.
Instead of that, you should do this:
if let data = result["picture"]?!["data"]
{
if let url = data!["url"] as? String
{
let profilePictureURL = url
let imgURL = NSURL(string: profilePictureURL)
let imageData = NSData(contentsOfURL: imgURL!)
let image = UIImage(data: imageData!)
print(image)
self.foto = image!
performSegueWithIdentifier("nextfb", sender: self)
}
}
This way you only go to the next controller when your data has successfully populated on your view controller.