How to clear cache of safari in iOS app? [duplicate] - ios

This question already has an answer here:
Alamofire clear all cookies
(1 answer)
Closed 6 years ago.
Please dont mark as Duplicate because I have tried all things but not working plz some one help me.
My app is having google sign in, while sign in I am getting all the previous signed-in accounts. How to remove those accounts?
Thank you in advance.
//MARK:- clear Cache
URLCache.shared.removeAllCachedResponses()
URLCache.shared.diskCapacity = 0
URLCache.shared.memoryCapacity = 0
self.deleteCoreData()
GIDSignIn.sharedInstance().disconnect()
GIDSignIn.sharedInstance().signOut()
for cookie in HTTPCookieStorage.shared.cookies! {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
// Removes cache for all responses
URLCache.shared.removeAllCachedResponses()
Sorry, For duplicate question but I tried above code but its not working. Can please anyone guide me where am I wrong ?
Thank you again.

For Swift 3.0, clear all URL cache and cookies like this
URLCache.shared.removeAllCachedResponses()
if let cookies = HTTPCookieStorage.shared.cookies {
for cookie in cookies {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
}

Try to remove specific cookie, related to auth, e.g.:
var cookieProperties = [HTTPCookiePropertyKey:String]()
cookieProperties[.name] = "<cookie_name>"
cookieProperties[.domain] = "<domain>"
cookieProperties[.originURL] = "<origin_url>"
// <... etc ...>
if let cookie = HTTPCookie(properties: cookieProperties) {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
or just remove all cookies, if it's not a problem in your case:
if let cookies = HTTPCookieStorage.shared.cookies {
for cookie in cookies {
HTTPCookieStorage.shared.deleteCookie(cookie)
}
}

Related

Save userDefault token after Login

I am new in software and I have a question.
I have LoginPage called LoginVC(screenshot as below).When the user opened the app first time, if the member login with his username and password or via Facebook account, next time he opened the app he will pass the login screen and show the "NewsVC" directly. If he logged out, he will see the Login Page again.
According to my investigations I must use UserDefault method and create a local database(for example SQLite). Probably it creates a access token for the entered users. But I don't know how I will do. Maybe there is the question about this problem in this site but because of I don't know in a detailed manner couldn't find the topic.
Can you explain this topic and share an example with a simple Swift 3 code.
Thanks in advance
LoginVC ScreenShot
Securitywise, it is considered a bad practice to store login tokens in UserDefaults, I'd suggest using Keychain API instead.
"Hackers" can relatively easy read data from UserDefaults and use your access token.
Keychain API is a bit hard to use, I'd suggest trying a 3rd party library, here is one example:
https://github.com/jrendel/SwiftKeychainWrapper
More info about securing your data on iOS:
https://github.com/felixgr/secure-ios-app-dev
If you are just learning - it is OK to use UserDefaults, but once you consider moving your app to production - refactor it to Keychain.
Try following Helper method
Set User ID
func setCurrentLoginID(_ struserid: String) {
UserDefaults.standard.set(struserid, forKey:"userID")
}
Check User Login or Not
func isUserLoggedIN() -> Bool {
let str = UserDefaults.standard.object(forKey: "userID") as! String
return str.characters.count > 0 ? true : false
}
Get User ID
func loggedUserId() -> String {
let str = UserDefaults.standard.object(forKey: "userID") as? String
return str == nil ? "" : str!
}
For Logout
func logout() {
UserDefaults.standard.set(nil, forKey: "userID")
}
Assuming you wanted to know how to implement this then you can store and get the value like below:-
let default = UserDefaults.standard
default.set(accessToken, forKey: "accessToken")
default.synchronized()
//Now get like this and use guard so that it will prevent your crash if value is nil.
guard let accessTokenValue = default.string(forKey: "accessToken") else {return}
print(accessTokenValue)

WKWebview injecting cookie header cause redirect loop

I'm trying to inject session cookies I've acquired separately into a WKWebview request, which turns out to be quite a pain...
I managed to inject the session cookies using this solution, as follows:
// Acquiring the cookies
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: s.request!.url!)
//Appending all the cookies into one raw string.
var cookiesRawString = ""
for c in cookies {
cookiesRawString += "\(c.name)=\(c.value); "
}
var req: URLRequest = try! URLRequest(url: URL, method: method)
// Then the injection itself
request.setValue(cookiesRawString, forHTTPHeaderField: "Cookie")
webView.load(req)
Let me quickly explain the server logic with pseudo code:
Server receive call to endpoint /endpoint1 with initial session cookies appended
It then proceed to redirect the client to /endpoint2 with user generated token appended in the url.
requesting the second endpoint with token appended results in the final redirect to /endpoint3 with Set-Cookie header containing one time session cookies
/endpoint3 with the one time session cookies appended results in 200 response, and the user is recognized.
The problem is that for some reason the when I append the cookies to the initial request using the method above, it results with a redirect loop, while on the Android platform it works flawless (I used there a similar injection method).
The only difference that I saw between them was that the android app injected the cookies only on the initial request, and all the subsequent redirect calls were without those session cookies.
While the ios repeated the initial session cookies on all the redirect calls (even ignoring the server set-cookie header and appending the initial session cookies..).
Am I doing something wrong? How can I make the wkwebview use the injected cookies only on the initial request?
Edit 1: Also tried falling back to UIWebview, but it produces the same results, it seems that injecting the cookies as a header is not good, but I tried using HTTPCookieStorage, but it won't save the cookies!
// the count is 7
var cookiesCount = HTTPCookieStorage.shared.cookies(for: s.request!.url!)?.count
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: s.request!.url!)
for c in cookies {
HTTPCookieStorage.shared.setCookie(c)
}
// Count is still 7!
cookiesCount = HTTPCookieStorage.shared.cookies(for: s.request!.url!)?.count
Edit 2:
Well I found out the UIWebview is using a global instance of the cookie storage, the same as alamofire (which I've used to fetch the session cookies), so there was no need to add the cookies manually, the site recognized the user.
But I still prefer to use WKWebview, as the UIWebview memory leak sky rockets (over 100 mb after couple of web pages navigation!).
Is there a way to use the global cookie jar (used by alamofire) in WKWebview??
I think this might be unrelated, but i had a similar issue.
The reason was the modified cookie was messing up all my subsequent request using NSURL.sharedSession. It turns out the cookie set using WKWebView was wiping out the headers from NSURLSession.sharedSession. I think the cookie storage is shared across multiple sessions. So, i ended up using EphemeralSession, instead of sharedSession.
I managed to get it working on WKWebview, using a hackish solution:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction:
WKNavigationAction, decisionHandler:
#escaping (WKNavigationActionPolicy) -> Void) {
let url = navigationAction.request.url!.absoluteString
if UserAppendix.isLogin && url != previousNavigateUrl {
previousNavigateUrl = url
if url.contains("/endpoint1") {
let headerFields = navigationAction.request.allHTTPHeaderFields
let headerIsPresent = headerFields!.keys.contains("Cookie")
if headerIsPresent {
decisionHandler(WKNavigationActionPolicy.allow)
} else {
var req = URLRequest(url: navigationAction.request.url!)
let cookies = NetworkAppendix.httpSessionCookies
let values = HTTPCookie.requestHeaderFields(with: cookies)
req.allHTTPHeaderFields = values
webView.load(req)
decisionHandler(WKNavigationActionPolicy.cancel)
}
}
else if firstTime {
firstTime = false
let req = URLRequest(url: navigationAction.request.url!)
webView.load(req)
decisionHandler(WKNavigationActionPolicy.cancel)
}
else {
decisionHandler(.allow)
}
}
else {
decisionHandler(.allow)
}
}
I set the cookies on the first request, and on the second request break the flow and create a new request (with the redirect url), to avoid the session cookies I set on the first request, all subsequent requests are treated the same.
I know it's not perfect, but it gets the job done.

Alamofire clear all cookies

I need the user to be able to log out. When they log in now, a cookie gets saved automatically, that works fine. But I want to clear all cookies.
NSURLCache.sharedURLCache().removeAllCachedResponses()
This does not work
You can remove all the cookies specifically stored for an URL like this (Swift 3):
let cstorage = HTTPCookieStorage.shared
if let cookies = cstorage.cookies(for: url) {
for cookie in cookies {
cstorage.deleteCookie(cookie)
}
}

How do I add a rate me button to an app that has not been released?

So I am about to launch an app to the App Store. My issue is that I have a rate my app please button but I do not know the right code to insert there.
My fiends tried this on their app and said it was no good:
Does anybody know how I can fix this issue?
let iTunesReviewPageLink = "http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=1073785561&pageNumber=0&sortOrdering=2&type=Purple+Software&mt=8"
// Go directly to review page on App Store
if let url = NSURL(string: iTunesReviewPageLink) {
UIApplication.sharedApplication().openURL(url)
}
The only unknown thing is the ID, right? You can see the ID of your app before it is published - once you set it up in iTunes Connect.
If your app is not yet released, you haven't got an App Store link. So that's impossible.
In order to implement this functionality when your app is released, you can use the following code:
Swift 2
let appIDString = "APP_ID" // your app ID
let reviewsURLString = "http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?pageNumber=0&sortOrdering=1&type=Purple+Software&mt=8&id=\(appIDString)"
let reviewsURL = NSURL(string: reviewsURLString)
if reviewsURL != nil && UIApplication.sharedApplication().canOpenURL(reviewsURL!) {
UIApplication.sharedApplication().openURL(reviewsURL!)
}
else {
// handle situation if reviews url cannot be opened.
}
Swift 3
let appIDString = "APP_ID" // your app ID
let reviewsURLString = "http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?pageNumber=0&sortOrdering=1&type=Purple+Software&mt=8&id=\(appIDString)"
let reviewsURL = URL(string: reviewsURLString)
if reviewsURL != nil && UIApplication.shared.canOpenURL(reviewsURL!) {
UIApplication.shared.openURL(reviewsURL!)
}
else {
// handle situation if reviews url cannot be opened.
}
EDIT:
This links works in iOS 8 and 9 and links directly to reviews page of the app in App Store application.
I am not sure about iOS 7. Probably for iOS 7 you need to use different link.

Error when Facebook Open Graph Action shared from iOS (unsafe link)

I tried to share a Facebook Open Graph Action via official iOS SDK (last version) but for a few days now, this action returns an error and it has now stopped working.
The app passed the Facebook approval, including actions and related objects and it all seems correct.
Object creation and share action
// ############## OpenGraph - Arrive At a Marina
// Photo
var photoURL = ""
if let image = firstMarina.images.first {
photoURL = image.width1440
} else {
photoURL = "https://fbstatic-a.akamaihd.net/images/devsite/attachment_blank.png"
}
let photo = FBSDKSharePhoto(imageURL: NSURL(string: photoURL)!, userGenerated: false)
// Properties
let properties = [
"fb:app_id": "xxxxxxxxxxxxxxxxxxxxx",
"og:locale": NSLocale.preferredLanguages()[0].stringByReplacingOccurrencesOfString("-", withString: "_"),
"og:type": "smartsea:marina",
"og:title": firstMarina.name!.text,
"og:description": firstMarina.desc!.text,
"og:image": [photo],
"place:location:latitude": firstMarina.location!.lat,
"place:location:longitude": firstMarina.location!.lng
]
// Object
let object = FBSDKShareOpenGraphObject(properties: properties as [NSObject : AnyObject])
// Action
let action = FBSDKShareOpenGraphAction(type: "smartsea:arrive_at", object: object, key: "marina")
// Content
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "marina"
// Share
FBSDKShareDialog.showFromViewController(self, withContent: content, delegate: self)
and the error returned
Error Domain=com.facebook.Facebook.platform Code=102 "(null)" UserInfo={error_reason=The content you're trying to share includes a link that our security systems detected to be unsafe:
https://m.facebook.com/appcenter/smartsea?fbs=9909&fb_object_id=1684374595135519
Please remove this link to continue., error_description=An error occurred during publishing., app_id=xxxxxxxxxxxxxxxxxxxxx, error_code=102}
The strange thing is that the error URL is a Facebook domain and I haven't share it this URL directly. It seems to be generated with every share action.
Any idea?
Thanks!
Unfortunately I can't post a simple comment, so I have to post it as an 'answer'. I have found this article. It's about blocked URLs, but unfortunately not about blocked 'Facebook' URLs. I hope it can help.
http://www.technerves.com/2015/07/unblock-your-website-url-from-facebook.html
It connection might be getting blocked due to App transport security. App transport security is a new thing introduced in iOS9.
It blocks connections to servers that don't meet certain security requirements, such as minimum TLS version etc
Please try again after turning ATS OFF from info.plist. See this link which shows how to turn ATS OFF.

Resources