Something like Callback in Swift - ios

have a problem with my web service written in Swift.
Starting the web service runs perfectly and the method connectionDidFinishLoading (WebServiceHelper) gets the right data.
Now I wanna call an individual function (in this case in LoginViewController, later in other Controllers), depending on which function started the web service.
In JavaScript I would use callbacks, but can't find something like this in Swift documentation.
class WebServiceHelper: NSObject, NSURLConnectionDelegate, NSXMLParserDelegate {
var mutableData:NSMutableData = NSMutableData()
var sourceClass:String = ""
var lastUsedService:String = ""
func startWebServiceActivity(xmlMessage:String, method:String, service:String) {
let text: String = xmlMessage
let wsUrl: String = "https://.../webservice/soap/server.php"
let soapMessage:String = text
let url = NSURL(string: wsUrl)
let theRequest = NSMutableURLRequest(URL: url!)
let msgLength = String(soapMessage.characters.count)
theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length")
theRequest.HTTPMethod = "POST"
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
let connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
// Parse the result right after loading
func connectionDidFinishLoading(connection: NSURLConnection!) {
//print(mutableData)
let datastring = String(data: mutableData, encoding: NSUTF8StringEncoding)
//print(datastring)
let result = XMLParser.sharedParser.decode(datastring!)
print(result)
}
}
class LoginViewController: UIViewController {
//MARK: IBOutlets
#IBOutlet weak var usernameTextfield: UITextField!
#IBOutlet weak var passwordTextfield: UITextField!
#IBOutlet weak var autoLoginSwitch: UISwitch!
//MARK: Properties
var soapMethod:String = "login"
var username:String = ""
var password:String = ""
let soapMessages:SOAPMessages = SOAPMessages()
//MARK: Functions
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton
}
//MARK: IBActions
#IBAction func confirmButton(sender: UIButton) {
username = usernameTextfield.text!
password = passwordTextfield.text!
let loginXML:String = soapMessages.getLoginXML(username, password: password)
WebServiceHelper().startWebServiceActivity(loginXML,method: soapMethod, service:"login")
}
}
Thanks your your Help

Delegates are the other way of doing it, closures also preferred though

Related

Load gif into WKwebView and integrate interval timer.... uikit. Thanks

I am beginner so please take in advance. I am trying to show some gifs up on eby one i got in the assets folder, so i do not know how to display and put time through in those pics, because i have already got the way to show the wkwebview but i cannot get gif into WKwebView one by one with intervals among them.
Here is the code:
import UIKit
import WebKit
class SecondWebKitView: UIViewController {
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var greyView: UIView!
#IBOutlet weak var webKitView: WKWebView!
let totalCount = 13
var count = 1
var myTimer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
greyView.layer.cornerRadius = 10
let url = Bundle.main.url(forResource: "1.JumpingJacks", withExtension: "gif")!
let data = try! Data(contentsOf: url)
webKitView.load(data, mimeType: "image/gif", characterEncodingName: "UTF-8", baseURL: NSURL() as URL)
webKitView.scalesLargeContentImage = true
webKitView.contentMode = UIView.ContentMode.scaleAspectFit
let jsonUrlString = "https://fitness-db.p.rapidapi.com/7-minute-workout"
guard let url = URL(string: jsonUrlString) else {return}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else {return}
do {
let websiteDescription = try JSONDecoder().decode(SecondWebKitModel.self, from: data)
print(websiteDescription.description ?? "", websiteDescription.description ?? "", websiteDescription.title ?? "")
//let courses = try JSONDecoder().decode([Course].self, from: data)
DispatchQueue.main.async {
self.descriptionLabel.text = websiteDescription.description
}
} catch let jsonErr {
print("Error serializing json", jsonErr)
}
}.resume()
}
#IBAction func start(sender: AnyObject) {
myTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: Selector(("myPerformeCode:")), userInfo: nil, repeats: true)
}
func myPerformeCode(timer : Timer) {
print("Displayed")
count += 1
if count < totalCount {
let filePath = Bundle.main.path(forResource: "\(count)", ofType: "gif")
let gif = NSData(contentsOfFile: filePath!)
self.webKitView.load(gif! as Data, mimeType: "image/gif",characterEncodingName: String(), baseURL: NSURL() as URL)
self.webKitView.isUserInteractionEnabled = false
} else {
count = 1
}
}
}
Need to solve how to show gifs up with timing. Thanks

How to Open Request in Browser in cellphone

I have a problem with an open request in my app. My apps sends a request to a web view and I need to open this request in a browser on a cellphone. I can not get it to open or perform the request in the web browser.
when I use the command code only can string format of URL.
How I can do request?
I use the command code string format of URL. How I can issue this request?
import UIKit
class PaymentViewController: UIViewController, UIWebViewDelegate {
var delegate: BackProtocol? = nil
var firstCall = true
var providerId: Int!
var transactionId: String!
#IBOutlet weak var webView: UIWebView!
func configureView() {
self.navigationItem.title = LocalizationSystem.sharedInstance.localizedStringForKey(key: "pay" , comment:"")
// back button
self.navigationItem.addCustomButton(style: .action, position: .left, customView: UIView())
if LocalizationSystem.sharedInstance.getLanguage() == "fa" {
self.navigationItem.addBackButtonEnglishLanguage(target: self, selector: #selector(onBackPressed))
} else {
self.navigationItem.addBackButton(target: self, selector: #selector(onBackPressed))
}
self.webView.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
self.configureView()
var request = URLRequest(url: URL(string: String(format: "%#%#",
Downloader.API_BASE_URL,
String(format: Downloader.API_PAYMENT_URL, transactionId,
providerId, Statics.CALLBACK_URL)))!)
request.httpMethod = "GET"
request.setValue(UserInfo.acessToken!, forHTTPHeaderField: "Authorization")
self.webView.loadRequest(request)
// guard let url = URL(string: "http://www.google.com") else {
// return //be safe
// }
//
// if #available(iOS 10.0, *) {
// UIApplication.shared.open(url, options: [:], completionHandler: nil)
// } else {
// UIApplication.shared.openURL(url)
// }
}
func webViewDidFinishLoad(_ webView: UIWebView) {
if let requestedUrl = webView.request?.mainDocumentURL?.absoluteString {
let parts = requestedUrl.components(separatedBy: "/")
// return to previous page
if parts[3] == "verify_payment" {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) { // 2 seconds later
self.onBackPressed()
}
}
}
}
}

Swift Instagram API username isn't displayed on label

I just wanna make an iOS app with Instagram API then I can see the user profile.
I just wrote this Code on my Xcode project to make iOS app.
here is the code :--
#IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
signInRequest()
}
func signInRequest() {
let getURL = String(format: "%#?client_id=%#&redirect_uri=%#&response_type=token&scope=%#&DEBUG=True", arguments: [API.INSTAGRAM_AUTHURL,API.INSTAGRAM_CLIENT_ID,API.INSTAGRAM_REDIRECT_URI,API.INSTAGRAM_SCOPE])
let request = URLRequest.init(url: URL.init(string: getURL)!)
webView.loadRequest(request)
}
func checkRequestForCallbackURL(request: URLRequest) -> Bool {
let requestURLString = (request.url?.absoluteString)! as String
if requestURLString.hasPrefix(API.INSTAGRAM_REDIRECT_URI) {
let range: Range<String.Index> = requestURLString.range(of: "#access_token=")!
handleAuth(authToken: requestURLString.substring(from: range.upperBound))
return false
}
return true
}
func handleAuth(authToken: String) {
let url = String(format: "https://api.instagram.com/v1/users/self/?access_token=%#", authToken)
let request: NSMutableURLRequest = NSMutableURLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let session = URLSession(configuration: .default)
session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
if let data = data {
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary
let strFullName = (json?.value(forKey: "data") as AnyObject).value(forKey: "full_name") as! String
let secondVC: SecondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "secondSeg") as! SecondViewController
secondVC.text = strFullName
self.present(secondVC
, animated: true, completion: nil)
}
}.resume()
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
return checkRequestForCallbackURL(request: request)
}
}
my question is when I run my app and want to see the instagram user username I can't see on my label.
I can't see the user (full_name, username, followers, etc...)
here is secondVC Code.
var text: String = ""
#IBOutlet weak var userNameLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
userNameLabel?.text = text
}
I believe your viewdidload function is being called before the update of your text variable
Try replacing:
var text: String = ""
With:
var text: String = "" {
didSet {
userNameLabel?.text = text
}
}

sign in on instagram from mobile device

I'm currently trying to sign into instagram from my application. I've been following this tutorial. However it's written in objective-c so I rewrote it to swift 3.0 (I hope lol).
However it doesn't seem to work like it's supposed to. It seems like it doesn't get the appropriate url request. Maybe I've done something wrong, maybe the tutorial I've used is outdated. I couldn't seem to find any others tho.
This is how my rewritten code looks.
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet var loginWebView: UIWebView!
#IBOutlet var loginactivity: UIActivityIndicatorView!
#IBOutlet var loadedlabel: UILabel!
var consumer: OAConsumer!;
var requestToken: OAToken!;
var accessToken: OAToken!;
var receivedData: Data!
var isLogin: String!;
var typeOfAuthentication: String!;
var client_id:String = "";
var secret:String = "";
var callback:String = "";
var authURL:String = "";
var scope: String = "";
override func viewDidLoad() {
super.viewDidLoad();
super.viewDidAppear(true);
client_id = "myid";
secret = "mysecret";
callback = "http://whattodo.com/";
typeOfAuthentication = "UNSIGNED";
scope = "likes+comments+relationships"
var authURL: String = "";
if(typeOfAuthentication == "UNSIGNED"){
authURL = String(format: "client_id=%#&redirect_uri=%#&response_type=token&scope=%#&DEBUG=true",
client_id, callback, scope);
}
else{
authURL = String(format: "client_id=%#&redirect_uri=%#&response_type=code&scope=%#&DEBUG=true", client_id, callback, scope);
}
loginWebView.loadRequest(URLRequest(url: URL(string: authURL)!));
loginWebView.delegate = self;
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
return checkRequestForCallbackURL(request: request);
}
func webViewDidStartLoad(_ webView: UIWebView) {
loginactivity.startAnimating();
loadedlabel.isHidden = false;
loginWebView.layer.removeAllAnimations();
loginWebView.isUserInteractionEnabled = false;
UIView.animate(withDuration: 0.1, animations: {
self.loginWebView.alpha = 0.2;
})
}
func webViewDidFinishLoad(_ webView: UIWebView) {
loginactivity.stopAnimating();
loadedlabel.isHidden = true;
loginWebView.layer.removeAllAnimations();
loginWebView.isUserInteractionEnabled = true;
UIView.animate(withDuration: 0.1, animations: {
self.loginWebView.alpha = 1;
})
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
self.webViewDidFinishLoad(webView);
}
func checkRequestForCallbackURL(request: URLRequest) -> Bool{
let urlString: String = (request.url?.absoluteString)!
if(typeOfAuthentication == "UNSIGNED"){
if(urlString.hasPrefix(callback)){
let range: Range = urlString.range(of: "access_token=")!;
let test: String = String(describing: range);
handleAuth(authToken: String(describing: range));
return false;
}
}
else{
if(urlString.hasPrefix(callback)){
let range: Range = urlString.range(of: "code")!;
let test: String = String(describing: range);
makePostRequest(code: String(describing: range))
return false;
}
}
return true;
}
func makePostRequest(code: String){
let post: String = String(format: "client_id=%#&client_secret=%#&grant_type=authorization_code&redirect_uri=%#&code=%#", client_id, secret, callback, code)
let postDate: Data = post.data(using: String.Encoding.ascii, allowLossyConversion: true)!;
let postLength: String = "\(UInt(postDate.count))"
let requestData: NSMutableURLRequest = NSMutableURLRequest(url: URL.init(string: "https://api.instagram.com/oauth/access_token")!);
requestData.httpMethod = "POST";
requestData.setValue(postLength, forHTTPHeaderField: "Content-Length");
requestData.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type");
requestData.httpBody = postDate;
var response: URLResponse? = nil;
let requestError: NSError? = nil;
var responseData: Data = try! NSURLConnection.sendSynchronousRequest(requestData as URLRequest, returning: &response);
let dict: NSDictionary = try! JSONSerialization.jsonObject(with: responseData, options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
handleAuth(authToken: dict["access_token"]! as! String)
}
func handleAuth(authToken: String){
NSLog("Successfully logged in with token: " + authToken);
}
}
I've made sure that disable implicit OAuth and enforce signed requests are both deselected. I also don't see anything strange showing up in my logs.
Does anyone know where I'm going wrong?

Cannot display part of JSON data

I've been trying to display certain JSON data to the storyboard but for some reason have been unable. The part of it that works, is the the var name, which is a string, and it doesn't have to be converted so it just works. The part that I am having an issue with is trying to convert two Int64's to strings, but I have them listed as AnyObjects. It's really confusing me, but here is the issue in code:
The program runs fine, but it doesn't display any information for profileIconId and summonerLevel.
import UIKit
class ViewController: UIViewController, NSURLConnectionDelegate {
lazy var data = NSMutableData()
#IBOutlet weak var searchField: UITextField!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var summonerLevel: UILabel!
#IBOutlet weak var profileIconId: UILabel!
#IBAction func enterButton(sender: AnyObject) {
startConnection()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startConnection(){
let urlPath: String = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/soon2challenger?api_key=(removed my private api key for obvious reasons)"
var url: NSURL = NSURL(string: urlPath)!
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)!
connection.start()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
self.data.appendData(data)
}
func buttonAction(sender: UIButton!){
startConnection()
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
let include: AnyObject = jsonResult.objectForKey(searchField.text)!
var name1: AnyObject = include.objectForKey("name")!
var summLevel: AnyObject = include.objectForKey("summonerLevel")!
var profIconId: AnyObject = include.objectForKey("profileIconId")!
name.text = name1 as? String
profileIconId.text = profIconId as? String
summonerLevel.text = summLevel as? String
println(name1)
println(summLevel)
println(profIconId)
}
}
The code that processes and displays everything is in the connectionDidFinishLoading function at the very bottom of the code.
Here's a refactor of your connectionDidFinishLoading(_:) method that properly unwraps the values using optional bindings.
You might also consider using NSNumberFormatter instead of "\()".
func connectionDidFinishLoading(connection: NSURLConnection) {
var err: NSError?
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary,
let include = jsonResult.objectForKey(searchField.text) as? NSDictionary {
if let name1 = include[ "name" ] as? String {
name.text = name1
println(name1)
}
if let summLevel = include[ "summonerLevel" ] as? NSNumber {
summonerLevel.text = "\(summLevel.integerValue)"
println(summLevel)
}
if let profIconId = include[ "profileIconId" ] as? NSNumber {
profileIconId.text = "\(profIconId.integerValue)"
println(profIconId)
}
}
}

Resources