I am trying to use the XMPP framework(https://github.com/robbiehanson/XMPPFramework) using swift.
I am new to swift
class ViewController: UIViewController {
var password: NSString?
var isOpen: Bool = false
var xstream: XMPPStream?
var loginServer: String = ""
override func viewDidLoad() {
super.viewDidLoad()
println(connect())
// 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.
}
func connect() ->Bool{
var xstream = XMPPStream()
var error: NSError?
xstream.addDelegate(self, delegateQueue: dispatch_get_main_queue())
xstream.myJID = XMPPJID.jidWithString("test#localhost")
xstream.hostName="127.0.0.1"
xstream.hostPort=5222
var password = "testing"
if !xstream.connectWithTimeout(XMPPStreamTimeoutNone, error: &error) {
println(error)
}
println(xstream.isConnecting()) // This prints true
return xstream.isConnected();// This prints false.
}
}
The username and password and server details are correct because i use adium to connect to server and it works fine.
Set your host name and port.
Call methods as described below.
configureXMPP()
configureXMPPElements()
loginWithId("userId", password: "password")
After this, delegate methods will be called and authentication will be done.
After authentication, one must send presence.
self.xmppStream.send(XMPPPresence())
private var hostName: String = "your host name"
private var hostPort: UInt16 = 5222
private var xmppStream: XMPPStream!
private var xmppReconnect: XMPPReconnect!
private var xmppRoster: XMPPRoster!
private var xmppvCardStorage: XMPPvCardCoreDataStorage!
private var xmppvCardTempModule: XMPPvCardTempModule!
private var xmppvCardAvatarModule: XMPPvCardAvatarModule!
private var xmppCapabilities: XMPPCapabilities!
private var xmppCapabilitiesStorage: XMPPCapabilitiesCoreDataStorage!
private var xmppMessageArchivingStorage: XMPPMessageArchivingCoreDataStorage!
private var xmppMessageArchivingModule: XMPPMessageArchiving!
private var xmppAutoPing: XMPPAutoPing!
private var userId = ""
private var password = ""
fileprivate func configureXMPP() {
// Stream Configuration
xmppStream = XMPPStream()
xmppStream.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppStream.hostPort = hostPort
xmppStream.hostName = hostName
xmppStream.enableBackgroundingOnSocket = true
xmppStream.keepAliveInterval = 0.5;
xmppStream.startTLSPolicy = .required
}
fileprivate func configureXMPPElements() {
//Autoping
xmppAutoPing = XMPPAutoPing(dispatchQueue: DispatchQueue.main)
xmppAutoPing?.activate(xmppStream)
xmppAutoPing?.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppAutoPing?.pingInterval = 2
xmppAutoPing?.pingTimeout = 2
// Reconnect
self.xmppReconnect = XMPPReconnect()
// Storage
let xmppRosterStorage = XMPPRosterCoreDataStorage()
self.xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage, dispatchQueue: DispatchQueue.main)
self.xmppRoster.autoFetchRoster = true
self.xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = true
self.xmppvCardStorage = XMPPvCardCoreDataStorage.sharedInstance()
self.xmppvCardTempModule = XMPPvCardTempModule(vCardStorage: xmppvCardStorage)
self.xmppvCardAvatarModule = XMPPvCardAvatarModule(vCardTempModule: xmppvCardTempModule)
self.xmppCapabilitiesStorage = XMPPCapabilitiesCoreDataStorage.sharedInstance()
self.xmppCapabilities = XMPPCapabilities(capabilitiesStorage: xmppCapabilitiesStorage)
self.xmppMessageArchivingStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
self.xmppMessageArchivingModule = XMPPMessageArchiving(messageArchivingStorage: xmppMessageArchivingStorage)
self.xmppMessageArchivingModule.clientSideMessageArchivingOnly = false
self.xmppMessageArchivingModule.activate(self.xmppStream)
self.xmppMessageArchivingModule.addDelegate(self, delegateQueue: DispatchQueue.main)
//Activate xmpp modules
self.xmppReconnect.activate(self.xmppStream)
self.xmppRoster.activate(self.xmppStream)
self.xmppvCardTempModule.activate(self.xmppStream)
self.xmppvCardAvatarModule.activate(self.xmppStream)
self.xmppCapabilities.activate(self.xmppStream)
// Add ourself as a delegate to anything we may be interested in
self.xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main)
}
func loginWithId(_ userId: String, password: String) {
if self.xmppStream == nil {
establishConnection()
}
self.userId = userId
self.password = password
xmppStream.myJID = XMPPJID(string: userId)
do {
try xmppStream?.connect(withTimeout: XMPPStreamTimeoutNone)
} catch {
print("connection failed")
}
}
fileprivate func authentictae() {
do {
try self.xmppStream.authenticate(withPassword: password)
}
catch {
print("not authenticate")
}
}
// Delegate Methods
func xmppStream(_ sender: XMPPStream!, socketDidConnect socket: GCDAsyncSocket!) {
print("socketDidConnect:")
sender.enableBackgroundingOnSocket = true
}
func xmppStreamDidStartNegotiation(_ sender: XMPPStream!) {
print("xmppStreamDidStartNegotiation:")
}
func xmppStreamDidConnect(_ sender: XMPPStream!) {
authentictae()
print("Stream: Connected")
}
func xmppStreamDidAuthenticate(_ sender: XMPPStream!) {
print("Stream: Authenticated")
}
Remember the connection takes some seconds to be established.
Use the other delegate methods to track the state of the connection.
Related
Current Scenario?:
Th registered user of the book app gets the notifications such as 'books available for download', q&A portal answers, live streaming link.
What is the goal?:
To get the notifications for guest where it can show the available books for download, and other notification that comes for registered user.
What is the issue/errors?:
When user clicks on the notification button , nothing comes on the screen. Everything blank and no notification is shown. It show the below error::
What i tried?:
When we call API, the token is generated from the backend. This token is then used to get the access. I tried to copy the API method to the home-screen that is used from 'signUpVC'(sign up view controller) to get the token bit showing above error.
Admin user notification looks as below:
Guest user (notification from our android app)
Code: for SignUp
import UIKit
import PKHUD
import SDWebImage
class SignupVC: ThemeController {
// MARK: - Outlets
#IBOutlet weak var imgProfile: TappableImageView!
#IBOutlet weak var passwordView: UIStackView!
#IBOutlet weak var lblRegister: UILabel!
var isFromUpdateProfile = Bool()
// -----------------------------------------------------------------------------------------------
// MARK: - Class Properties
#IBOutlet weak var txtFirstName: UITextField!
#IBOutlet weak var txtLastName: UITextField!
#IBOutlet weak var txtEmail: UITextField!
#IBOutlet weak var txtCity: UITextField!
#IBOutlet weak var txtPassword: UITextField!
// -----------------------------------------------------------------------------------------------
// MARK: - Memory Management Functions
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
deinit {
}
// -----------------------------------------------------------------------------------------------
// MARK: - Class Functions
private func errorsInTextFields() -> String? {
self.view.endEditing(true)
guard !txtFirstName.isEmpty else { return UserMessages.kBlankFirstName }
guard txtFirstName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidFirstName }
guard !txtLastName.isEmpty else { return UserMessages.kBlankLastName }
guard txtLastName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidLastName }
guard !txtEmail.isEmpty else { return UserMessages.kBlankEmail }
guard txtEmail.hasValid(.email) else { return UserMessages.kValidEmail }
guard !txtCity.isEmpty else { return UserMessages.kBlankCity }
guard txtCity.hasValid(.alphabetWithSpace) else { return UserMessages.kValidCity }
guard !txtPassword.isEmpty else { return UserMessages.kBlankPassword }
//guard txtPassword.hasValid(.password) else { return UserMessages.kValidPassword }
// No Errors
return nil
}
private func errorsInEditProfileTextFields() -> String? {
self.view.endEditing(true)
guard !txtFirstName.isEmpty else { return UserMessages.kBlankFirstName }
guard txtFirstName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidFirstName }
guard !txtLastName.isEmpty else { return UserMessages.kBlankLastName }
guard txtLastName.hasValid(.alphabetWithSpace) else { return UserMessages.kValidLastName }
guard !txtEmail.isEmpty else { return UserMessages.kBlankEmail }
guard txtEmail.hasValid(.email) else { return UserMessages.kValidEmail }
guard !txtCity.isEmpty else { return UserMessages.kBlankCity }
guard txtCity.hasValid(.alphabetWithSpace) else { return UserMessages.kValidCity }
// No Errors
return nil
}
// -----------------------------------------------------------------------------------------------
// MARK: - Action Functions
#IBAction func btnRegisterAction(_ sender: RoundButton) {
if let _ = User.current?.accessToken{
//TextField Verification
if let error = errorsInEditProfileTextFields() {
SnackBar.show(error)
return
}
//API Calling
self.apiEditProfileCall()
}else{
//TextField Verification
if let error = errorsInTextFields() {
SnackBar.show(error)
return
}
//API Calling
apiRegisterDeviceCall()
}
}
// -----------------------------------------------------------------------------------------------
// MARK: - Web Service Functions
private func apiRegisterDeviceCall() {
HUD.show(.progress)
var deviceToken:String = UserDefaults.standard.string(forKey: "DeviceToken") ?? "empty"
let parameters: [String: Any] = [
"vDeviceUniqueId" : DeviceManager.deviceUniqueId,
"txDeviceToken" : deviceToken,
"tDeviceOs" : DeviceManager.deviceOS,
"vDeviceName" : DeviceManager.modelName,
"vResolution" : DeviceManager.resolution,
"vOsVersion" : DeviceManager.osVersion,
]
print(parameters)
APIManager.shared.makeRequest(method: .registerDevice, parameters: parameters, withLoader: false) { (response, error) in
print(response)
if let accessToken = response["data"]["access_token"].string {
UserDefaults.standard.setValue(accessToken, forKey: "AccessToken")
self.apiRegisterCall()
} else {
HUD.hide()
SnackBar.show("Something went wrong")
}
}
}
private func apiRegisterCall() {
let parameters: [String: Any] = [
"vFirstName" : txtFirstName.trimmedText,
"vLastName" : txtLastName.trimmedText,
"vEmail" : txtEmail.trimmedText,
"vPassword" : txtPassword.trimmedText,
"vCityName" : txtCity.trimmedText,
]
var images: [String: UIImage] = [:]
if let image = imgProfile.image {
images["txProfileImageUrl"] = image
}
APIManager.shared.makeRequest(method: .registerUser, parameters: parameters, imageParameters: images, withLoader: false) { (response, error) in
HUD.hide()
if response["data"].exists() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.popViewController()
}
// Alert.showWith("User Registered", message: "Please check your email inbox for varification email", positiveTitle: "Ok", shouldResignOnTouchOutside: false) { isOk in
// if isOk {
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
// self.popViewController()
// }
// }
// }
} else {
SnackBar.show(response["message"].stringValue)
}
}
}
private func apiEditProfileCall() {
HUD.show(.progress)
let parameters: [String: Any] = [
"vFirstName" : txtFirstName.trimmedText,
"vLastName" : txtLastName.trimmedText,
"vEmail" : txtEmail.trimmedText,
"vCityName" : txtCity.trimmedText,
]
var images: [String: UIImage] = [:]
if let image = imgProfile.image {
images["txProfileImageUrl"] = image
}
APIManager.shared.makeRequest(method: .editProfile, parameters: parameters, imageParameters: images, withLoader: false) { (response, error) in
HUD.hide()
if response["data"].exists(){
if let accessToken = User.current?.accessToken{
var updateUser = User(withJSON: response["data"])
updateUser.accessToken = accessToken
User.current = updateUser
SnackBar.show("Profile successfully updated.")
self.navigationController?.popViewControllers(viewsToPop: 2)
}
}else{
SnackBar.show(response["message"].stringValue)
}
}
}
// -----------------------------------------------------------------------------------------------
// MARK: - Life Cycle Functions
override func viewDidLoad() {
super.viewDidLoad()
if let _ = User.current?.accessToken{
self.passwordView.isHidden = true
self.lblRegister.text = "Update"
self.title = "Edit Profile"
self.imgProfile.sd_imageIndicator = SDWebImageActivityIndicator.gray
self.imgProfile.sd_setImage(with: URL(string: User.current!.profileImage), placeholderImage: nil)
self.txtFirstName.text = User.current!.firstName
self.txtLastName.text = User.current!.lastName
self.txtEmail.text = User.current!.email
self.txtCity.text = User.current!.cityName
}
}
// -----------------------------------------------------------------------------------------------
}
I have ChatsocketIO class which handles all the SocketIO functions related to the chat functionality of the app. The skeleton of that class looks like below.
My Question is when the Socket receives a message it fires the "socket!.on("msg")", However i am confused how to pass this back to the view controller class which i am calling this API class. I have added the View Controller class as well below..
class ChatServiceAPI {
// MARK: - Properties
var manager: SocketManager? = nil
var socket: SocketIOClient? = nil
//Chat Variables
var items:[Message] = []
// MARK: - Life Cycle
init() {
setupSocket()
setupSocketEvents()
socket?.connect()
}
static let shared = ChatServiceAPI();
func stop() {
socket?.removeAllHandlers()
}
// MARK: - Socket Setup
func setupSocket() {
socket = manager!.defaultSocket;
}
func setupSocketEvents() {
if socket!.status != .connected{
socket!.connect()
}
socket!.on(clientEvent: .connect) { (data, emitter) in
print("==connecting==");
}
socket!.on("msg") { (data, emitter) in
let mesage = Message()
let jsonObject = JSON(data[0])
let messageString: String? = jsonObject["msg"].string
let userIDFrom: Int? = jsonObject["profile"]["id"].int
if(userIDFrom != Int(self.userIDTo)) {
return
}
if( userIDFrom == nil)
{
return
}
mesage.data = JSON(["from_user": self.userIDTo, "to_user": self.userID, "msg": self.convertStringToHtmlCode(msg: messageString ?? ""), "created": Date().description(with: .current)])
self.items.insert(mesage, at: 0)
//self.viewMessagesList.reload(messages: self.items, conversation: self.conversation)
}
socket!.on("disconnect") { (data, emitter) in
print("===disconnect==");
self.isConnected = false
}
socket!.connect();
}
// MARK: - Socket Emits
func register(user: String) {
socket?.emit("add user", user)
}
func send(message: String, toUser: String) {
let data = NSMutableDictionary()
data.setValue(message, forKey: "msg")
data.setValue(toUser.lowercased(), forKey: "to")
socket!.emit("send", data);
return;
}
}
In My View Controller, I have something like below, I want to pass ChatSocketAPI's "self.items" to the below-calling controller, when a msg comes, I am confused about how to do this?
import UIKit
import SocketIO
import SwiftyJSON
import EZAlertController
class MessagingViewController: UIViewController {
let viewMessagesList = MessagesListViewController()
let bottomMenuChatView = BottomMenuChatView(frame: CGRect.zero)
var isAnimation = false
let emojiView = EmojiView(frame: CGRect.zero)
func setupSocketIO() {
ChatServiceAPI.init();
self.socket = ChatServiceAPI.shared.socket;
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupSocketIO()
ChatServiceAPI.shared.page = 0;
ChatServiceAPI.shared.items = []
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.setupNavigation()
if Reachability.isConnectedToNetwork() == false {
EZAlertController.alert("", message: "Please check your internet connection")
return
}
// bottom menu setup
bottomMenuChatView.btnSendMessage.addTarget(self, action: #selector(tappedBtnSendMessage(btn:)), for: .touchUpInside)
bottomMenuChatView.btnEmoji.addTarget(self, action: #selector(tappedBtnEmoji(btn:)), for: .touchUpInside)
bottomMenuChatView.textFieldMessage.delegate = self
}
Make your MessagingViewController a listener for the ChatServiceAPI. You can implement that like this:
Create a protocol like the following:
protocol MessageListener: AnyObject {
func messageReceived(text: String)
}
and make you controller conform to it:
extension MessagingViewController: MessageListener {
func messageReceived(text: String) {
// do whatever you need with the message
}
}
Then, in the ChatServiceAPI you can create a var named listeners:
private var listeners: [MessageListener] = []
and methods for adding and removing listeners:
func add(listener: MessageListener) {
self.listeners.append(listener)
}
func remove(listener: MessageListener) {
self.listeners.remove(listener)
}
For the last part, in your ChatServiceAPI, when the "msg" event is received, you need to send the message to all of your registered listeners. So, something like this:
socket!.on("msg") { (data, emitter) in
...
for listener in self.listeners {
listener.messageReceived(text: ...)
}
}
Now you also need to register your viewController as a listener. So you would call ChatServiceAPI.shared.add(listener: self) in your viewDidLoad.
Don't forget to also call ChatServiceAPI.shared.remove(listener: self) to prevent memory leaks.
You can back data to your view controller by writing socket.ON inside a function that have escaping block.
Here is my sample code that I use
func getResponse(completion: #escaping(_ resMessage: String) -> Void) {
guard let socket = manager?.defaultSocket else {
return
}
socket.on(myEventName) { (dataArray, socketAck) -> Void in
guard let data = UIApplication.jsonData(from: dataArray[0]) else {
return
}
do {
let responseMsg = try JSONDecoder().decode(String.self, from: data)
completion(responseMsg)
} catch let error {
print("Something happen wrong here...\(error)")
completion("")
}
}
}
Then you can call this function getResponse in viewDidLoad inside your viewController. Like this -
self.socketInstance.getResponse { socketResponse in
// socketResponse is the response
// this will execute when you get new response from socket.ON
}
We have fragmented movie data that comes through WebSecureSocket (wss://). We are writing that into a temp.mp4 and simultaneously playing the fragments that got written into the file. So, we used AVFragmentedAsset and AVFragmentedAssetMinder for this. It works as expected in the simulator. But in the device, doesn't update the duration of the asset and doesn't post the .AVAssetDurationDidChange notification. Not sure what could be the issue. Already spent 2 days figuring out this but no luck. Can someone help me with this please,
Implementation..
public class WssPlayerSource: WebSocketDelegate {
static let ASSET_MINDER = AVFragmentedAssetMinder()
private let socketClient: WebSocketStreamingClient
private var tempMovieFile:FileHandle? = nil
private var startedPlay = false
private var fragmentedAsset: AVFragmentedAsset? = nil
let player = AVPlayer()
init(withUrl url: URL) {
socketClient = WebSocketStreamingClient(wssUrl: url)
socketClient.delegate = self
do {
self.tempMovieFile = try getTemporaryMovieFileWriter()
}catch {
print("Error opening file")
}
NotificationCenter.default.addObserver(self, selector: #selector(onVideoUpdate), name: .AVAssetDurationDidChange, object: nil)
socketClient.connect()
}
// Socket delegate
public func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .binary(let data):
self.tempMovieFile?.write(data)
if !startedPlay {
startedPlay = true
DispatchQueue.global().async { [weak self] in
self?.didReceivedInitialData()
}
}
break;
default:
break;
}
}
func didReceivedInitialData() {
fragmentedAsset = AVFragmentedAsset(url: getTemporaryMovieFile()!)
fragmentedAsset?.loadValuesAsynchronously(forKeys: ["duration", "containsFragments", "canContainFragments"], completionHandler: {
WssPlayerSource.ASSET_MINDER.mindingInterval = 1
WssPlayerSource.ASSET_MINDER.addFragmentedAsset(self.fragmentedAsset!)
self.player.replaceCurrentItem(with: AVPlayerItem(asset: self.fragmentedAsset!))
self.player.play()
})
}
#objc
func onVideoUpdate() {
print("Video duration updated..")
// This is not called in device.. but in simulator it works as expected
}
func stop() {
socketClient.forceDisconnect()
NotificationCenter.default.removeObserver(self)
if let asset = self.fragmentedAsset {
WssPlayerSource.ASSET_MINDER.addFragmentedAsset(asset)
}
}
}
And
class ViewController: UIViewController {
#IBOutlet var playerView:PlayerView!
private static let SOCKET_URL = "wss://..."
private var playerSource:WssPlayerSource? = nil
private var playerLayer:AVPlayerLayer? = nil
override func viewDidLoad() {
super.viewDidLoad()
self.playerSource = WssPlayerSource(withUrl: URL(string: ViewController.SOCKET_URL)!)
self.playerLayer = AVPlayerLayer(player: self.playerSource!.player)
self.playerLayer?.videoGravity = .resize
self.playerView.layer.addSublayer(self.playerLayer!)
}
}
I'm having a bit of confusion on how to properly create a SINCall object. I understand that SINCall is a type protocol, and in swift I tried to create it as such:
var _call: SINCall?
When I try to call, my app crashes because the _call is nil.
However, if I do add SINCall to the list of protocols next to SINCallDelegate, and SINCallClientDelegate, I get the error that I'm not conforming to the SINCall protocol.
class CallViewController: UIViewController, SINCallDelegate, SINCallClientDelegate {
var userName: String? {
didSet {
}
}
var recepientUser: String? {
didSet {
}
}
var _call: SINCall?
var appKey = "xxx"
var appSecret = "xxx"
var host = "xxx"
var client: SINClient {
return Sinch.clientWithApplicationKey(appKey, applicationSecret: appSecret, environmentHost: host, userId: userName!)
}
override func viewDidLoad() {
super.viewDidLoad()
print("Lock and load")
client.callClient().delegate = self
client.setSupportCalling(true)
client.start()
client.startListeningOnActiveConnection()
callUser()
}
func callUser() {
self._call = client.callClient().callUserWithId(self.recepientUser!)
self._call!.delegate = self
}
func client(client: SINCallClient!, didReceiveIncomingCall call: SINCall!) {
call.delegate = self
self._call = call
self._call!.answer()
}
// callDidProgress, callDidEstablish, callDidEnd implemented below ...
Is the client started when you make the call, it can take a few seconds so you should probably start the the client in the app delegate when its launched, and then when the client is started you can do a call, you probably get nil now because the client is not started
I am currently working on an app and I am having an issue. When the user login the webservice, if the login is successful the server responds with JSON, where we use the "firstName" and "SecondName" to then create our "User" which is a struct defined in another file called User.swift . Then, what I want to do is user the "firstName" that has been given to the "User struct" as a UILabel in my homepageview that comes after a successful login. when I try to give my label User.prenom(which is firstName in french) I get the error: User.type does not have a member called...
Here is my code:
the client file where the Login Method is defined:
import Foundation
import Alamofire
import SwiftyJSON
private let _instance = Client()
class Client {
// Router is used to do a request to the server.
private enum Router: URLRequestConvertible {
private static let baseURL = "https://mobile.uqam.ca/portail_etudiant/"
// stores the authentication token.
static var code_perm: String?
static var nip:String?
// Login request.
case Login(String, String)
// URLRequestConvertible protocol.
var URLRequest: NSURLRequest {
// Returns the path, http method and parameters for the request.
var (path: String, method: Alamofire.Method, parameters: [String: AnyObject]) = {
switch self {
case .Login (let code_perm, let nip):
let params: [String: AnyObject] = [
"code_perm": code_perm,
"nip": nip,
]
return ("proxy_dossier_etud.php", .POST, params)
}
}()
// Setup the URLRequest.
let url = NSURL(string: Router.baseURL)
let urlRequest = NSMutableURLRequest(URL: url!.URLByAppendingPathComponent(path))
urlRequest.HTTPMethod = method.rawValue
if let code_perm = Router.code_perm {
if let nip = Router.nip{
parameters["nip"] = nip
parameters["code_perm"] = code_perm
}
}
let encoding = Alamofire.ParameterEncoding.URL
return encoding.encode(urlRequest, parameters: parameters).0
}
}
// Singleton
class var sharedInstance: Client {
return _instance
}
private init() {}
// Login logs in the user with his email and password.
func login(code_perm:String, nip:String, callback:(LoginResponse?) -> Void) {
Alamofire.request(Router.Login(code_perm, nip)).responseJSON { (_, _, data, error) in
if(error != nil) {
callback(nil)
return
}
var json = JSON(data!)
let prenom = json["socio"]["prenom"].stringValue
let nom = json["socio"]["nom"].stringValue
Router.code_perm = code_perm
Router.nip = nip
callback(LoginResponse(
user: User(prenom: prenom,nom: nom)
))
}
}
}
the loginViewController where the login function is called
import UIKit
class LoginViewController: UIViewController {
#IBOutlet weak var LoginScreenImage: UIImageView!
#IBOutlet weak var codeTextField: UITextField!
#IBOutlet weak var nipTextField: UITextField!
#IBOutlet weak var loadingLogin: UIActivityIndicatorView!
let client = Client.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
LoginScreenImage.image = UIImage(named: "UQAMLOGO")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func connect() {
let code_perm = codeTextField.text
let nip = nipTextField.text
self.loadingLogin.startAnimating()
if code_perm != "" && nip != "" {
client.login(code_perm, nip: nip, callback: { (response) in
if let response = response {
self.loadingLogin.stopAnimating()
let homeViewController = self.storyboard!.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewController
self.showViewController(homeViewController, sender: self)
} else {
self.loadingLogin.stopAnimating()
let badLogin = UIAlertController(title: "Échec de connexion", message: "La combinaison du code permanent et du nip n'est pas bonne", preferredStyle: .Alert)
let reessayer = UIAlertAction(title: "Réessayer", style: .Default, handler: { (reessayer) -> Void in
self.dismissViewControllerAnimated(true , completion: nil)
})
badLogin.addAction(reessayer)
self.presentViewController(badLogin, animated: true, completion: nil)
}
})
}
}
}
the User.swift while where the user struct is
import Foundation
struct User {
var prenom :String
var nom: String
}
struct LoginResponse {
var user: User
}
and finally the HomePageViewController where I try to give the value to my label:
import UIKit
class HomeViewController: UIViewController {
#IBOutlet weak var schedule: UIImageView!
#IBOutlet weak var courses: UIImageView!
#IBOutlet weak var email: UIImageView!
#IBOutlet weak var grades: UIImageView!
#IBOutlet weak var bienvenueLabel: UILabel!
let client = Client.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
schedule.image = UIImage(named:"schedule")
courses.image = UIImage(named: "courses")
email.image = UIImage(named:"mail")
grades.image = UIImage(named:"grades")
bienvenueLabel.text = User.prenom
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thanks everyone for the help and have a great day/night
Charles
You are accessing the class instead of an instance. Instead, you should pass the response instance to your HomeViewController:
class HomeViewController : .. {
// ...
var loginResponse : LoginResponse
// ...
override func viewDidLoad() {
// ...
bienvenueLabel.text = loginResponse.user.prenom
}
}
// ...
client.login(code_perm, nip: nip, callback: { (response) in
if let loginResponse = response as LoginResponse {
self.loadingLogin.stopAnimating()
let homeViewController = self.storyboard!.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewController
homeViewController.loginResponse = loginResponse
// assign your instance ^^^^^^^^^^^^^^^^^^^^^^^^
self.showViewController(homeViewController, sender: self)
}
You are accessing the class instead of an instance. Instead, you should pass the response instance to your HomeViewController:
class HomeViewController : .. {
// ...
var loginResponse : LoginResponse
// ...
override func viewDidLoad() {
// ...
bienvenueLabel.text = loginResponse.user.prenom
}
}
// ...
client.login(code_perm, nip: nip, callback: { (response) in
if let loginResponse = response as LoginResponse {
self.loadingLogin.stopAnimating()
let homeViewController = self.storyboard!.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewController
homeViewController.loginResponse = loginResponse
// assign your instance ^^^^^^^^^^^^^^^^^^^^^^^^
self.showViewController(homeViewController, sender: self)
}
This really isn't very good structure, but it should at least answer your question.