I have a login to an API which works and now want to load a web view which needs the authentication token. I'm testing my app using the Xcode Simulator for iOS 10.1.
When I load the web view I get a sign in page and a message from the API "It looks like you are not accepting cookies". Is this a case of mismatched cookies names expected or something I have missed?
func createWebViewRequest() {
self.createCookie()
let url = URL (string: "myDomain/info/wishlists")
let requestObj = NSMutableURLRequest(url: url!)
requestObj.httpShouldHandleCookies = true
let headers = HTTPCookie.requestHeaderFields(with: HTTPCookieStorage.shared.cookies!)
requestObj.allHTTPHeaderFields = headers
requestObj.addValue("iOS", forHTTPHeaderField: "X-My-Client")
self.webview!.loadRequest(requestObj as URLRequest)
self.webview!.delegate = self
self.view.addSubview(self.webview!)
}
func createCookie() {
let infoModel = UserInfoManager.getUserInfoModel()
if infoModel != nil {
let cookieProps = NSMutableDictionary()
cookieProps.setValue("NIDDEV", forKey: HTTPCookiePropertyKey.name.rawValue)
cookieProps.setValue(infoModel?.userAccessToken, forKey: HTTPCookiePropertyKey.value.rawValue)
cookieProps.setValue(".mydomain.com", forKey: HTTPCookiePropertyKey.domain.rawValue)
cookieProps.setValue("/", forKey: HTTPCookiePropertyKey.path.rawValue)
cookieProps.setValue("0", forKey: HTTPCookiePropertyKey.version.rawValue)
cookieProps.setValue(Date().addingTimeInterval(31536000), forKey: HTTPCookiePropertyKey.expires.rawValue)
let dict:NSDictionary = cookieProps as NSDictionary
let cookie = HTTPCookie(properties: dict as! [HTTPCookiePropertyKey : Any])
HTTPCookieStorage.shared.setCookie(cookie!)
}
else {
let delegate = UIApplication.shared.delegate as! AppDelegate
delegate.callAuthTokenWebservice()
}
}
I dumped the create cookie method above and decided to save the cookies using the response header for the immediately prior check auth call which comes from an API and authenticates in the header. This stopped the target web site from complaining about not getting cookies but it still wouldn't accept the auth key.
private func setCookies(response: URLResponse) {
if let httpResponse = response as? HTTPURLResponse {
if let headerFields = httpResponse.allHeaderFields as? [String: String] {
let _ = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: response.url!)
// print(cookies)
}
}
}
Related
I wish to open app with the latest url viewd on a webview ios app.
Tryied this inside viewdidload()
var hasHistoryUrl = false
WebView.evaluateJavaScript("window.location.href") {
(result,error)->Void in if (result != nil){
hasHistoryUrl=true
}
}
if (hasHistoryUrl){
// let url = URL(string: historyUrl)
} else {
let url = URL(string: "https://www.url.com/")
let request = URLRequest(url: url!)
loadReq(request: request);
}
Not working on true device, on emulators allways opens with a clear cache.
When you open your app, all variable initialise and your previous data will be gone. So you need to save latest visited url in userdefaults as string like-
let url: String = "abcd.com"
UserDefaults.standard.set(url, forKey: "MyUrl")
And fetch url from userdefaults when you open the app as -
if let urlString = UserDefaults.string(forKey: ""MyUrl"") {
// Do stuff
}
In your code, insert it as-
WebView.evaluateJavaScript("window.location.href") {
(result,error)->Void in if (result != nil){
UserDefaults.standard.set(yourURL, forKey: "MyUrl")
}
}
if let urlString = UserDefaults.string(forKey: ""MyUrl"") {
// Do stuff
} else {
let url = URL(string: "https://www.url.com/")
let request = URLRequest(url: url!)
loadReq(request: request);
}
I am calling API in iOS (swift). Everything works perfectly, but it's taking too much time while getting response approximately 40 or 60 seconds. I don't know why this is happening. Let me show you my API calling method:
Code
func userDetailAPI(){
let preferences = UserDefaults.standard
let uid = "u_id"
let acctkn = "acc_tkn"
if preferences.object(forKey: uid) == nil {
// Doesn't exist
} else {
let u_id = preferences.object(forKey: uid) as! String
print(u_id)
let acc_tkn = preferences.object(forKey: acctkn) as! String
print(acc_tkn)
let userprofile: [String : Any] = ["user_id":u_id,"access_token":acc_tkn]
print(userprofile)
Alamofire.request(userDetails, method: .post, parameters: userprofile).responseJSON { response in
print("RESPONSE : \(response)")
let result = response.result.value
if result != nil{
let data = result as! [String : AnyObject]
let userdata = data["data"] as! NSDictionary
let email = userdata["email"]
let name = userdata["name"]
let photo = userdata["photo"]
//let u_type = userdata["user_type"]!
self.lblUserName.text = name as? String
self.lblEmailID.text = email as? String
let proimgurl = NSURL(string: photo as! String)
self.imgProPic.image = UIImage(data: NSData(contentsOf: proimgurl! as URL)! as Data)
// }
}
}
}
}
Please check and help me - is this the right method for API calling or is there any other, better way?
Because of this line
self.imgProPic.image = UIImage(data: NSData(contentsOf: proimgurl! as URL)! as Data)
so you have almofire request plus blocking main thread until image is downloaded , so consider using the asynchronous , automatic cashing SDWebImage
self.imgProPic.sd_setImage(with: proimgurl!, placeholderImage: UIImage(named: "placeholder.png"))
Also in swift avoid using NS stuff like here
let userdata = data["data"] as! NSDictionary // use [String:Any]
and
let proimgurl = NSURL(string: photo as! String) // use URL
You should download the ImageView's image from Url in another thread. If you do it in the main thread, it'll slow down your app and ultimately run out of memory.
The below-given line is which causes the problem is below
self.imgProPic.image = UIImage(data: NSData(contentsOf: proimgurl! as URL)! as Data)
I suggest you use the SDWebImage library.
You can do like something below
let imageUrl = URL(string: photo as! String)
self.imgProPic.image.sd_setImage(with: imageUrl, placeholderImage: UIImage(named: "profile"), options: .refreshCached, completed: nil)
If this doesn't solve your problem, try calling the same web service using API clients such as Postman. If it's taking the same amount of time, then you can't do much about it. Ask the web service developer to optimize the performance.
Hey by the way there is also alamofire image pod is available.
https://github.com/Alamofire/AlamofireImage
eg:
do import AlamofireImage into your file and call image url like below:
Alamofire.request(image_url, method: .get).responseImage(completionHandler: { (response) in
self.your_UIImage_variable.image = response.result.value
})
I use oAuth for the users login.
func getUserInfoResponse(_ response: APIResponse!) {
print("----------------------------------------")
print("用户资料获取成功:")
print(response.jsonResponse)
//print(response.jsonResponse["figureurl_qq_2"])
let accessToken = _tencentOAuth.accessToken
let nickname = response.jsonResponse["nickname"] as! String!
let avatar = response.jsonResponse["figureurl_qq_1"] as! String!
let avatar2 = response.jsonResponse["figureurl_qq_2"] as! String!
let urlString:String = "http://www.xxxxxx.com/cloud/app?openid=\(accessToken!)&nickname=\(nickname!)&avatar=\(avatar!)&avatar2=\(avatar2!)"
self.wk = WKWebView(frame: self.view.frame)
let url = URL(string: urlString)!
self.wk.load(URLRequest(url: url))
self.view.addSubview(self.wk)
}
and print(urlString) is
http://www.example.com/cloud/app?openid=xxxxxxx32D1E05D95E91881A15A8CDC75&nickname=
.&avatar=http://q.qlogo.cn/qqapp/101237639/90012AB5E745A1B10A6F5F4A14F0B48D/40&avatar2=http://q.qlogo.cn/qqapp/101237639/90012AB5E745A1B10A6F5F4A14F0B48D/100
when user login, , all the values have value except the url and get this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Why the url is nil, it has been assigned with value. Sorry I'm new to ios and swift3.
You should encode the url before use it
if let urlEncoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed){
let url = URL(string: urlEncoded)
}
I'm trying to get user image from twitter(parse- twitter login) using this code :
if PFTwitterUtils.isLinkedWithUser(PFUser.currentUser()!) {
let screenName = PFTwitterUtils.twitter()?.screenName!
let requestString = NSURL(string: "https://api.twitter.com/1.1/users/show.json?screen_name=" + screenName!)
let request = NSMutableURLRequest(URL: requestString!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
PFTwitterUtils.twitter()?.signRequest(request)
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
print(data)
print(response)
print(error)
if error == nil {
var result: AnyObject?
do {
result = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
} catch let error2 as NSError? {
print("error 2 \(error2)")
}
let names: String! = result?.objectForKey("name") as! String
let separatedNames: [String] = names.componentsSeparatedByString(" ")
//self.firstName = separatedNames.first!
//self.lastName = separatedNames.last!
let urlString = result?.objectForKey("profile_image_url_https") as! String
let hiResUrlString = urlString.stringByReplacingOccurrencesOfString("_normal", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
let twitterPhotoUrl = NSURL(string: hiResUrlString)
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
self.userImg = UIImageView(image: twitterImage)
}
}).resume()
}
but it imageData is nil
let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
let twitterImage: UIImage! = UIImage(data:imageData!)
twitterphotoUrl actually have the link
any help???
I would guess that you're getting an ATS exception from the pbs.twimg.com URL, so you're not getting the data, so you fall over when you force unwrap it. You should add that domain to the list of ATS exceptions as shown here, [documented here] (https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html) (search for NSExceptionDomain on that page) and discussed in many other places.
In addition to that, force unwrapping the results of URL calls is always a bad idea, since any number of things could prevent a data object being created. You should be using guard or if let statements in this case.
Try with below code,
if let imageData = NSData(contentsOfURL: twitterPhotoUrl!)
{
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.userImg.image = UIImage(image: imageData!)
})
}
Hope this will work
I've integrated login with vk button in my ios app. And I want to add an ability to switch account.
I've tried to run network request to http://api.vk.com/oauth/logout. But it outputs wrong logout hash.
I used this code:
let logoutUrl = "http://api.vk.com/oauth/logout"
let request = NSMutableURLRequest(URL: NSURL(string: logoutUrl)!,
cachePolicy:.ReloadIgnoringLocalCacheData,
timeoutInterval:60.0)
let responseData = try! NSURLConnection.sendSynchronousRequest(request, returningResponse: nil)
Also I tried to clear NSDefaults, after logout:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.removeObjectForKey("VKAccessUserId")
defaults.removeObjectForKey("VKAccessToken")
defaults.removeObjectForKey("VKAccessTokenDate")
defaults.synchronize()
And to clear cookies:
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
for cookie in storage.cookies {
let domainName = cookie.domain
let domainRange = domainName.rangeOfString("vk.com")
if(domainRange.length > 0) {
storage.deleteCookie(cookie)
}
}
And nothing helps
I found the solution. Should call VKSdk.forceLogout()