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()
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 have iOS application, that you need to login to, and view some user data...
For some extra edit, I have url link to page, where can user set some special properties,... but it is really annoying for users to login inside page, if they are already logged in application.
For this reason I need to store custom cookies in HTTPCookieStorage, so that when user navigate to the page, authentication cookies would be set for him.
How to create custom cookie with key-value, and store it so that Safari will use it when user navigate to my page?
EDIT
I will provide more information to better understand my situation.
I have one button inside my app.
After clicking to this button, I call API to get valid token.
After receiving token, I need to store this token as cookies. The "server" way of doing this would be
localStorage.setItem('token', this.token)
After I would store this token into HTTPCookieStorage, I will open my page.
UIApplication.shared.open(myURL, options: [:], completionHandler: { (success) in
print("Url open")
})
In page on myURL, the application look for a token cookies. If cookies exist it open web app, else it presents login page.
So my goal is to prevent opening login page.
Store your cookies:
func storeCookies() {
let cookiesStorage = HTTPCookieStorage.shared
let userDefaults = UserDefaults.standard
let serverBaseUrl = "http://example.com"
var cookieDict = [String : AnyObject]()
for cookie in cookiesStorage.cookies(for: NSURL(string: serverBaseUrl)! as URL)! {
cookieDict[cookie.name] = cookie.properties as AnyObject?
}
userDefaults.set(cookieDict, forKey: "cookiesKey")
}
Retrieve:
func restoreCookies() {
let cookiesStorage = HTTPCookieStorage.shared
let userDefaults = UserDefaults.standard
if let cookieDictionary = userDefaults.dictionary(forKey: "cookiesKey") {
for (_, cookieProperties) in cookieDictionary {
if let cookie = HTTPCookie(properties: cookieProperties as! [HTTPCookiePropertyKey : Any] ) {
cookiesStorage.setCookie(cookie)
}
}
}
}
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)
}
}
}
I want to create a iOS App with 2 Webviews (1 Shop, 1 Logged-In Shop)
If I login in one webview, the other webview includes the same cookies and the first webview is logged in too.
I need the first one to have it's own session (cookies)!
My plan is to have a saved login Touch-ID protected and a free everyone can use webview.
I was currently searching for 2 and a half hours and tried stuff like:
let request = NSMutableURLRequest(URL: NSURL(string: "https://www.my-url.com")!)
request.setValue("", forHTTPHeaderField: "Cookie")
webView.loadRequest(request)
Yes , you can save your cookies to the first webview from webViewDidFinishLoad:
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
for cookie in storage.cookies as! [NSHTTPCookie]{
print(cookie)
}
NSUserDefaults.standardUserDefaults().synchronize()
If you set to the second webview to the loadRequest:
var req = NSURLRequest(URL: NSURL(string: urlString)!)
var storage = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies as! [NSHTTPCookie]
var reqCookies:[AnyObject] = []
for aCookie in storage {
reqCookies += [aCookie]
}
var headers = NSHTTPCookie.requestHeaderFieldsWithCookies(reqCookies)
self.webView.loadRequest(req)
Otherwise you can delete:
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
for cookie in storage.cookies! {
storage.deleteCookie(cookie)
}
NSUserDefaults.standardUserDefaults().synchronize()
EDIT (after comments): to manage different sessions you can look in this Stackoverflow answer to handle your different sessions.
I have this requirement to download .p12 file(certificate) from a vendor and make it available on my app for the user to install it on to his device.
Now If I attach a .p12 file to email and when the recipient clicks on the file on iphone it will start installing I am just trying to get the same behavior.
As of now in my app I am able to download the p12 file and store it in the apps documents directory.
func saveCert(serialId : String){
let source = "https://myhost.com/serialId"
let url = NSURL(string: source)
let request = NSURLRequest(URL: url!)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if (error == nil) {
let statusCode = (response as! NSHTTPURLResponse).statusCode
print("Success: \(statusCode)")
let filename = self.getDocumentsDirectory().stringByAppendingPathComponent("test.p12")
print(filename)
data?.writeToFile(filename, atomically: true)
let filemgr = NSFileManager.defaultManager()
if filemgr.fileExistsAtPath(filename) {
print("File exists")
} else {
print("File not found")
}
}
else {
print("Faulure: %#", error!.localizedDescription);
}
});
task.resume()
}
Now i need to open this file so user will be taken to install profile screens. Please help.
Here is what you want to look at.
and here is an example of how to use it
import Security
let fileManager = NSFileManager.defaultManager()
var resourcePath:String = fileManager.currentDirectoryPath
resourcePath = resourcePath.stringByAppendingString("/dummy.p12")
if fileManager.fileExistsAtPath(resourcePath){
let p12Data: NSData = NSData(contentsOfFile: resourcePath)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "password_for_certificate"]
//create variable for holding security information
var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
let securityError: OSStatus = SecPKCS12Import(p12Data, options, &items)
}
Hope that gets you most of the way there.
Edit:
After doing more research, I found this lib that will help you do everything you are looking to do.
Give it a try.