我正在使用UIWebView
这是我的代码
import UIKit
typealias LinkedInLoginCallBack = ([String:String]?,String,Error?) -> Void
class LinkedInWebViewController: UIViewController,UIWebViewDelegate {
@IBOutlet weak var linkedinWebView: UIWebView!
@IBOutlet weak var indicator: UIActivityIndicatorView!
var userDidLogin:LinkedInLoginCallBack!
let linkedInKey = "xxxx"
let linkedInSecret = "xxxx"
let authorizationEndPoint = "https://www.linkedin.com/uas/oauth2/authorization"
let accessTokenEndPoint = "https://www.linkedin.com/uas/oauth2/accessToken"
override func viewDidLoad() {
super.viewDidLoad()
linkedinWebView.delegate = self
self.startAuthorization()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func startAuthorization() {
let responseType = "code"
let redirectURL = "https://example.com/login/check-linkedin".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!
let state = "xxxxx"
let scope = "r_basicprofile,r_emailaddress"
var authorizationURL = "\(authorizationEndPoint)?"
authorizationURL += "response_type=\(responseType)&"
authorizationURL += "client_id=\(linkedInKey)&"
authorizationURL += "redirect_uri=\(redirectURL)&"
authorizationURL += "state=\(state)&"
authorizationURL += "scope=\(scope)"
// logout already logined user or revoke tokens
logout()
// Create a URL request and load it in the web view.
let request = URLRequest(url: URL(string: authorizationURL)!)
linkedinWebView.loadRequest(request)
}
func logout(){
let revokeUrl = "https://api.linkedin.com/uas/oauth/invalidateToken"
let request = URLRequest(url: URL(string: revokeUrl)!)
linkedinWebView.loadRequest(request)
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
let url = request.url!
if url.host == "https://example.com/login/check-linkedin" {
if url.absoluteString.range(of: "code") != nil {
let urlParts = url.absoluteString.components(separatedBy: "?")
let code = urlParts[1].components(separatedBy: "=")[1]
requestForAccessToken(authorizationCode: code)
}
}
return true
}
func webViewDidStartLoad(_ webView: UIWebView) {
indicator.startAnimating()
}
func webViewDidFinishLoad(_ webView: UIWebView) {
indicator.stopAnimating()
}
func requestForAccessToken(authorizationCode: String) {
let grantType = "authorization_code"
let redirectURL = "https://example.com/login/check-linkedin".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
// Set the POST parameters.
var postParams = "grant_type=\(grantType)&"
postParams += "code=\(authorizationCode)&"
postParams += "redirect_uri=\(redirectURL)&"
postParams += "client_id=\(linkedInKey)&"
postParams += "client_secret=\(linkedInSecret)"
// Convert the POST parameters into a NSData object.
let postData = postParams.data(using: String.Encoding.utf8)
// Initialize a mutable URL request object using the access token endpoint URL string.
let request = NSMutableURLRequest(url: NSURL(string: accessTokenEndPoint)! as URL)
// Indicate that we're about to make a POST request.
request.httpMethod = "POST"
// Set the HTTP body using the postData object created above.
request.httpBody = postData
// Add the required HTTP header field.
request.addValue("application/x-www-form-urlencoded;", forHTTPHeaderField: "Content-Type")
// Initialize a NSURLSession object.
let session = URLSession(configuration: URLSessionConfiguration.default)
// Make the request.
let task: URLSessionDataTask = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
// Get the HTTP status code of the request.
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200 {
// Convert the received JSON data into a dictionary.
do {
let dataDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
print("dataDictionary\(dataDictionary)")
let accessToken = dataDictionary["access_token"] as! String
var socialAuth:[String:String] = [String:String]()
socialAuth[SignupAPIController.KEY_PARAM_SOCIAL_TYPE] = SocialMediaType.instagram.rawValue
socialAuth[SignupAPIController.KEY_PARAM_SOCIAL_ID] = dataDictionary["username"] as? String
socialAuth[SignupAPIController.KEY_PARAM_SOCIAL_TOKEN] = accessToken
socialAuth[SignupAPIController.KEY_PARAM_SOCIAL_RTOKEN] = accessToken
socialAuth["name"] = dataDictionary["full_name"] as? String
socialAuth["email"] = dataDictionary["username"] as? String
self.userDidLogin(socialAuth,accessToken,nil)
DispatchQueue.main.async {
self.dismiss(animated: true, completion: nil)
}
} catch {
print("Could not convert JSON data into a dictionary.")
}
}else{
print("cancel clicked")
}
}
task.resume()
}
}
但不知道一段时间后由于以下错误它会使我的应用程序崩溃
thread #20, name = 'WebThread', stop reason = EXC_BAD_ACCESS (code=1, address=0x2ffffff6b)
这是我的堆栈跟踪
(lldb) bt
* thread #16, name = 'WebThread', stop reason = EXC_BAD_ACCESS (code=1, address=0x2ffffff6b)
* frame #0: 0x000000018fda66e4 JavaScriptCore`llint_entry + 15716
frame #1: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #2: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #3: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #4: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #5: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #6: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #7: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #8: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #9: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #10: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #11: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #12: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #13: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #14: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #15: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #16: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #17: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #18: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #19: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #20: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #21: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #22: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #23: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #24: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #25: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #26: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #27: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #28: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #29: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #30: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #31: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #32: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #33: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #34: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #35: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #36: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #37: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #38: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #39: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #40: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #41: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #42: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #43: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #44: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #45: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #46: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #47: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #48: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #49: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #50: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #51: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #52: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #53: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #54: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #55: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #56: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #57: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #58: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #59: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #60: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #61: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #62: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #63: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #64: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #65: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #66: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #67: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #68: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #69: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #70: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #71: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #72: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #73: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #74: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #75: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #76: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #77: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #78: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #79: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #80: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #81: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #82: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #83: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #84: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #85: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #86: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #87: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #88: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #89: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #90: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #91: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #92: 0x000000018fda89d4 JavaScriptCore`llint_entry + 24660
frame #93: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #94: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #95: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #96: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #97: 0x000000018fca616c JavaScriptCore`JSC::boundThisNoArgsFunctionCall(JSC::ExecState*) + 448
frame #98: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #99: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #100: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #101: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #102: 0x000000018f6c75fc JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 352
frame #103: 0x000000018f93a2a8 JavaScriptCore`JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&, WTF::NakedPtr<JSC::Exception>&) + 164
frame #104: 0x0000000190340a10 WebCore`WebCore::JSEventListener::handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) + 992
frame #105: 0x00000001906748d8 WebCore`WebCore::EventTarget::fireEventListeners(WebCore::Event&, WebCore::EventTargetData*, WTF::Vector<WebCore::RegisteredEventListener, 1ul, WTF::CrashOnOverflow, 16ul>&) + 620
frame #106: 0x0000000190674588 WebCore`WebCore::EventTarget::fireEventListeners(WebCore::Event&) + 328
frame #107: 0x000000019067442c WebCore`WebCore::EventTarget::dispatchEvent(WebCore::Event&) + 108
frame #108: 0x00000001906743ac WebCore`WebCore::EventTarget::dispatchEventForBindings(WebCore::Event*, int&) + 116
frame #109: 0x00000001909eb22c WebCore`WebCore::jsEventTargetPrototypeFunctionDispatchEvent(JSC::ExecState*) + 260
frame #110: 0x000000018fda9450 JavaScriptCore`llint_entry + 27344
frame #111: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #112: 0x000000018fda8a38 JavaScriptCore`llint_entry + 24760
frame #113: 0x000000018fda27b8 JavaScriptCore`vmEntryToJavaScript + 264
frame #114: 0x000000018fc75a88 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 168
frame #115: 0x000000018f6b0480 JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 13724
frame #116: 0x000000018f9936f4 JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 440
frame #117: 0x0000000190ec88a0 WebCore`WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&, WebCore::ExceptionDetails*) + 328
frame #118: 0x0000000190224c84 WebCore`WebCore::ScriptElement::executeScript(WebCore::ScriptSourceCode const&) + 612
frame #119: 0x00000001902a0448 WebCore`WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent(WebCore::PendingScript&) + 212
frame #120: 0x000000019026b5a8 WebCore`WebCore::HTMLScriptRunner::executeScriptsWaitingForParsing() + 88
frame #121: 0x000000019078b53c WebCore`non-virtual thunk to WebCore::HTMLDocumentParser::notifyFinished(WebCore::CachedResource*) + 52
frame #122: 0x000000019029d8b8 WebCore`WebCore::CachedResource::checkNotify() + 448
frame #123: 0x000000019029d59c WebCore`WebCore::SubresourceLoader::didFinishLoading(double) + 1020
frame #124: 0x000000018c00e788 CFNetwork`__65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke + 80
frame #125: 0x000000018c00e718 CFNetwork`-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 200
frame #126: 0x000000018c00e88c CFNetwork`-[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 56
frame #127: 0x000000018bf393dc CFNetwork`___ZN27URLConnectionClient_Classic23_delegate_cacheTrifectaEPK20_CFCachedURLResponseU13block_pointerFvvE_block_invoke + 576
frame #128: 0x000000018bf34960 CFNetwork`___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 + 108
frame #129: 0x00000001033e921c libdispatch.dylib`_dispatch_client_callout + 16
frame #130: 0x00000001033f3c9c libdispatch.dylib`_dispatch_block_invoke_direct + 400
frame #131: 0x000000018bfebeb4 CFNetwork`RunloopBlockContext::_invoke_block(void const*, void*) + 36
frame #132: 0x000000018b6a79a8 CoreFoundation`CFArrayApplyFunction + 68
frame #133: 0x000000018bfebd98 CFNetwork`RunloopBlockContext::perform() + 136
frame #134: 0x000000018bfed0c0 CFNetwork`MultiplexerSource::perform() + 312
frame #135: 0x000000018bfece2c CFNetwork`MultiplexerSource::_perform(void*) + 64
frame #136: 0x000000018b77c278 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #137: 0x000000018b77bbc0 CoreFoundation`__CFRunLoopDoSources0 + 524
frame #138: 0x000000018b7797c0 CoreFoundation`__CFRunLoopRun + 804
frame #139: 0x000000018b6a8048 CoreFoundation`CFRunLoopRunSpecific + 444
frame #140: 0x000000019025845c WebCore`RunWebThread(void*) + 456
frame #141: 0x000000018a864850 libsystem_pthread.dylib`_pthread_body + 240
frame #142: 0x000000018a864760 libsystem_pthread.dylib`_pthread_start + 284
frame #143: 0x000000018a861dac libsystem_pthread.dylib`thread_start + 4