iOS OneDrive SDK-需要更新不推荐的UIWebView

iOS OneDrive SDK-需要更新不推荐的UIWebView,ios,onedrive,Ios,Onedrive,OneDriveSDK for iOS已经有一段时间没有更新了,它使用不推荐的UIWebView进行登录。苹果将停止接受使用UIWebView的应用程序。因为我们不知道Microsoft是否/何时更新此SDK,所以我想分享我使用WKWebView进行的代码更改。我的解决方案更新了ODAuthenticationViewController.m // Copyright 2015 Microsoft Corporation // // Permission is hereby granted,

OneDriveSDK for iOS已经有一段时间没有更新了,它使用不推荐的UIWebView进行登录。苹果将停止接受使用UIWebView的应用程序。因为我们不知道Microsoft是否/何时更新此SDK,所以我想分享我使用WKWebView进行的代码更改。

我的解决方案更新了ODAuthenticationViewController.m

//  Copyright 2015 Microsoft Corporation
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//  
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//  
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//


#import "ODAuthenticationViewController.h"
#import "ODAuthHelper.h"
#import "ODAuthConstants.h"

#define kRequestTimeoutDefault  60

@interface ODAuthenticationViewController() <WKNavigationDelegate>  // Ernie Ern2 UIWebVie_wDelegate

@property WKWebView *webView;   // Ern2

@property NSURLRequest *initialRequest;
@property (strong, nonatomic) ODEndURLCompletion successCompletion;
@property (strong, nonatomic) NSURL *endURL;

@property (strong, nonatomic) NSTimer *timer;
@property (nonatomic) BOOL isComplete;

@end

@implementation ODAuthenticationViewController

- (instancetype)initWithStartURL:(NSURL *)startURL
                          endURL:(NSURL *)endURL
                         success:(ODEndURLCompletion)sucessCompletion
{
    self = [super init];
    if (self){
        _endURL = endURL;
        _initialRequest = [NSURLRequest requestWithURL:startURL];
        _successCompletion = sucessCompletion;
        _requestTimeout = kRequestTimeoutDefault;
        _isComplete = NO;
    }
    return self;
}

- (void)cancel
{
    if (!self.isComplete)
    {
        [self.timer invalidate];
        self.timer = nil;
        self.isComplete = YES;
        
        NSError *cancelError = [NSError errorWithDomain:OD_AUTH_ERROR_DOMAIN code:ODAuthCanceled userInfo:@{}];
        if (self.successCompletion){
            self.successCompletion(nil, cancelError);
        }
    }
}

- (void)loadInitialRequest
{
    [self.webView loadRequest:self.initialRequest];
}

- (void)redirectWithStartURL:(NSURL *)startURL
                      endURL:(NSURL *)endURL
                      success:(ODEndURLCompletion)successCompletion
{
    self.endURL = endURL;
    self.successCompletion = successCompletion;
    self.initialRequest = [NSURLRequest requestWithURL:startURL];
    self.isComplete = NO;
    [self.webView loadRequest:self.initialRequest];
}

- (void)loadView
{
    self.webView = [[WKWebView alloc] init];
    // Ern2 [self.webView setScalesPageToFit:YES];
    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.webView.navigationDelegate = self; // Ern2
    self.view = self.webView;
    UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                target:self
                                                                                action:@selector(cancel)];
    self.navigationController.topViewController.navigationItem.leftBarButtonItem = cancel;
    
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.webView loadRequest:self.initialRequest];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self.webView stopLoading];
    self.webView.navigationDelegate = nil;
    [super viewWillDisappear:animated];
}

#pragma mark - UI_WebViewDelegate

// Ern2

- (void) webView: (WKWebView *) webView didStartProvisionalNavigation: (null_unspecified WKNavigation *) navigation {
    [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:self.requestTimeout target:self selector:@selector(failWithTimeout) userInfo:nil repeats:NO];
}
/*
- (void)webViewDidStartLoad:(UIWebVie_w *)webView
{
    [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:self.requestTimeout target:self selector:@selector(failWithTimeout) userInfo:nil repeats:NO];
} */

- (void) webView: (WKWebView *) webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    [self.timer invalidate];
    self.timer = nil;
}
/*
- (void)webViewDidFinishLoad:(UIWebVie_w *)webView
{
    [self.timer invalidate];
    self.timer = nil;
} */

- (void) webView: (WKWebView *) webView decidePolicyForNavigationAction: (WKNavigationAction *) navigationAction decisionHandler: (void (^)(WKNavigationActionPolicy)) decisionHandler {
    
    //NSLog(@"[ept] %@   %@", [navigationAction.request.URL absoluteString], [self.endURL absoluteString]);
    if ([[[navigationAction.request.URL absoluteString] lowercaseString] hasPrefix:[[self.endURL absoluteString] lowercaseString]]){
        self.isComplete = YES;
        [self.timer invalidate];
        self.timer = nil;
        
        self.successCompletion(navigationAction.request.URL, nil);
        decisionHandler(WKNavigationActionPolicyCancel);
    }
    else decisionHandler(WKNavigationActionPolicyAllow);
}

/*
- (BOOL)webView:(UIWebVie_w *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebVie_wNavigationType)navigationType
{
    if ([[[request.URL absoluteString] lowercaseString] hasPrefix:[[self.endURL absoluteString] lowercaseString]]){
        self.isComplete = YES;
        [self.timer invalidate];
        self.timer = nil;
        
        self.successCompletion(request.URL, nil);
        return NO;
    }
    return YES;
} */

- (void) webView: (WKWebView *) webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error {
    
    [self.timer invalidate];
    self.timer = nil;
    
    if (NSURLErrorCancelled == error.code)
    {
        //This is a common error that webview generates and could be ignored.
        //See this thread for details: https://discussions.apple.com/thread/1727260
        return;
    }
    
    if([error.domain isEqual:@"WebKitErrorDomain"]){
        return;
    }
    
    // Ignore failures that are triggered after we have found the end URL
    if (self.isComplete)
    {
        //We expect to get an error here, as we intentionally fail to navigate to the final redirect URL.
        return;
    }
    
    if (self.successCompletion) {
        self.successCompletion(nil, error);
    }
}
/*
- (void)webView:(UIWebVie_w *)webView didFailLoadWithError:(NSError *)error
{
    [self.timer invalidate];
    self.timer = nil;
    
    if (NSURLErrorCancelled == error.code)
    {
        //This is a common error that webview generates and could be ignored.
        //See this thread for details: https://discussions.apple.com/thread/1727260
        return;
    }
    
    if([error.domain isEqual:@"WebKitErrorDomain"]){
        return;
    }
    
    // Ignore failures that are triggered after we have found the end URL
    if (self.isComplete)
    {
        //We expect to get an error here, as we intentionally fail to navigate to the final redirect URL.
        return;
    }
    
    if (self.successCompletion) {
        self.successCompletion(nil, error);
    }
}
*/

- (void)failWithTimeout
{
    [self webView: self.webView didFailNavigation: nil withError: [NSError errorWithDomain: NSURLErrorDomain code: NSURLErrorTimedOut userInfo:nil]];
    //[self webView:self.webView didFailLoadWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil]];
}

@end
请参阅下面的代码。
我在更新的地方添加了注释“ern2”

在ADAL target/pod中,我删除了对4个引用我未使用的UIWebView的文件的引用。(如果您正在使用这些,则我的解决方案不起作用。)

ADAuthenticationViewController.h
ADAuthenticationViewController.m
ADAuthenticationWebViewController.h
ADAuthenticationWebViewController.m

//  Copyright 2015 Microsoft Corporation
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//  
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//  
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//


#import "ODAuthenticationViewController.h"
#import "ODAuthHelper.h"
#import "ODAuthConstants.h"

#define kRequestTimeoutDefault  60

@interface ODAuthenticationViewController() <WKNavigationDelegate>  // Ernie Ern2 UIWebVie_wDelegate

@property WKWebView *webView;   // Ern2

@property NSURLRequest *initialRequest;
@property (strong, nonatomic) ODEndURLCompletion successCompletion;
@property (strong, nonatomic) NSURL *endURL;

@property (strong, nonatomic) NSTimer *timer;
@property (nonatomic) BOOL isComplete;

@end

@implementation ODAuthenticationViewController

- (instancetype)initWithStartURL:(NSURL *)startURL
                          endURL:(NSURL *)endURL
                         success:(ODEndURLCompletion)sucessCompletion
{
    self = [super init];
    if (self){
        _endURL = endURL;
        _initialRequest = [NSURLRequest requestWithURL:startURL];
        _successCompletion = sucessCompletion;
        _requestTimeout = kRequestTimeoutDefault;
        _isComplete = NO;
    }
    return self;
}

- (void)cancel
{
    if (!self.isComplete)
    {
        [self.timer invalidate];
        self.timer = nil;
        self.isComplete = YES;
        
        NSError *cancelError = [NSError errorWithDomain:OD_AUTH_ERROR_DOMAIN code:ODAuthCanceled userInfo:@{}];
        if (self.successCompletion){
            self.successCompletion(nil, cancelError);
        }
    }
}

- (void)loadInitialRequest
{
    [self.webView loadRequest:self.initialRequest];
}

- (void)redirectWithStartURL:(NSURL *)startURL
                      endURL:(NSURL *)endURL
                      success:(ODEndURLCompletion)successCompletion
{
    self.endURL = endURL;
    self.successCompletion = successCompletion;
    self.initialRequest = [NSURLRequest requestWithURL:startURL];
    self.isComplete = NO;
    [self.webView loadRequest:self.initialRequest];
}

- (void)loadView
{
    self.webView = [[WKWebView alloc] init];
    // Ern2 [self.webView setScalesPageToFit:YES];
    self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.webView.navigationDelegate = self; // Ern2
    self.view = self.webView;
    UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                target:self
                                                                                action:@selector(cancel)];
    self.navigationController.topViewController.navigationItem.leftBarButtonItem = cancel;
    
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.webView loadRequest:self.initialRequest];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [self.webView stopLoading];
    self.webView.navigationDelegate = nil;
    [super viewWillDisappear:animated];
}

#pragma mark - UI_WebViewDelegate

// Ern2

- (void) webView: (WKWebView *) webView didStartProvisionalNavigation: (null_unspecified WKNavigation *) navigation {
    [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:self.requestTimeout target:self selector:@selector(failWithTimeout) userInfo:nil repeats:NO];
}
/*
- (void)webViewDidStartLoad:(UIWebVie_w *)webView
{
    [self.timer invalidate];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:self.requestTimeout target:self selector:@selector(failWithTimeout) userInfo:nil repeats:NO];
} */

- (void) webView: (WKWebView *) webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    [self.timer invalidate];
    self.timer = nil;
}
/*
- (void)webViewDidFinishLoad:(UIWebVie_w *)webView
{
    [self.timer invalidate];
    self.timer = nil;
} */

- (void) webView: (WKWebView *) webView decidePolicyForNavigationAction: (WKNavigationAction *) navigationAction decisionHandler: (void (^)(WKNavigationActionPolicy)) decisionHandler {
    
    //NSLog(@"[ept] %@   %@", [navigationAction.request.URL absoluteString], [self.endURL absoluteString]);
    if ([[[navigationAction.request.URL absoluteString] lowercaseString] hasPrefix:[[self.endURL absoluteString] lowercaseString]]){
        self.isComplete = YES;
        [self.timer invalidate];
        self.timer = nil;
        
        self.successCompletion(navigationAction.request.URL, nil);
        decisionHandler(WKNavigationActionPolicyCancel);
    }
    else decisionHandler(WKNavigationActionPolicyAllow);
}

/*
- (BOOL)webView:(UIWebVie_w *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebVie_wNavigationType)navigationType
{
    if ([[[request.URL absoluteString] lowercaseString] hasPrefix:[[self.endURL absoluteString] lowercaseString]]){
        self.isComplete = YES;
        [self.timer invalidate];
        self.timer = nil;
        
        self.successCompletion(request.URL, nil);
        return NO;
    }
    return YES;
} */

- (void) webView: (WKWebView *) webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error {
    
    [self.timer invalidate];
    self.timer = nil;
    
    if (NSURLErrorCancelled == error.code)
    {
        //This is a common error that webview generates and could be ignored.
        //See this thread for details: https://discussions.apple.com/thread/1727260
        return;
    }
    
    if([error.domain isEqual:@"WebKitErrorDomain"]){
        return;
    }
    
    // Ignore failures that are triggered after we have found the end URL
    if (self.isComplete)
    {
        //We expect to get an error here, as we intentionally fail to navigate to the final redirect URL.
        return;
    }
    
    if (self.successCompletion) {
        self.successCompletion(nil, error);
    }
}
/*
- (void)webView:(UIWebVie_w *)webView didFailLoadWithError:(NSError *)error
{
    [self.timer invalidate];
    self.timer = nil;
    
    if (NSURLErrorCancelled == error.code)
    {
        //This is a common error that webview generates and could be ignored.
        //See this thread for details: https://discussions.apple.com/thread/1727260
        return;
    }
    
    if([error.domain isEqual:@"WebKitErrorDomain"]){
        return;
    }
    
    // Ignore failures that are triggered after we have found the end URL
    if (self.isComplete)
    {
        //We expect to get an error here, as we intentionally fail to navigate to the final redirect URL.
        return;
    }
    
    if (self.successCompletion) {
        self.successCompletion(nil, error);
    }
}
*/

- (void)failWithTimeout
{
    [self webView: self.webView didFailNavigation: nil withError: [NSError errorWithDomain: NSURLErrorDomain code: NSURLErrorTimedOut userInfo:nil]];
    //[self webView:self.webView didFailLoadWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil]];
}

@end
//版权所有2015 Microsoft Corporation
//
//特此向任何获得副本的人免费授予许可
//本软件和相关文档文件(“软件”)的
//在软件中不受限制,包括但不限于权利
//使用、复制、修改、合并、发布、分发、再许可和/或销售
//软件的副本,并允许向其提供软件的人员
//按照以下条件提供:
//  
//上述版权声明和本许可声明应包含在
//软件的所有副本或主要部分。
//  
//本软件按“原样”提供,无任何形式的明示或明示担保
//默示,包括但不限于适销性保证,
//适用于特定目的和非侵权。在任何情况下
//作者或版权持有人应承担任何索赔、损害或其他责任
//无论是在合同诉讼、侵权诉讼或其他诉讼中,由以下原因引起的责任:,
//与本软件有关或与本软件的使用或其他交易有关
//软件。
//
#导入“ODAuthenticationViewController.h”
#导入“ODAuthHelper.h”
#导入“ODAuthConstants.h”
#定义kRequestTimeoutDefault 60
@接口ODAuthenticationViewController()//Ernie Ern2 UIWebVie\u wDelegate
@属性WKWebView*webView;//Ern2
@属性NSURLRequest*initialRequest;
@属性(强,非原子)ODEndURLCompletion successCompletion;
@属性(强,非原子)NSURL*endURL;
@属性(强,非原子)NSTimer*计时器;
@性质(非原子)布尔是完全的;
@结束
@身份验证ViewController的实现
-(instancetype)initWithStartURL:(NSURL*)startURL
endURL:(NSURL*)endURL
成功:(ODEndURLCompletion)成功完成
{
self=[super init];
如果(自我){
_endURL=endURL;
_initialRequest=[nsurlRequestRequestWithURL:startURL];
_successCompletion=成功完成;
_requestTimeout=kRequestTimeoutDefault;
_isComplete=否;
}
回归自我;
}
-(作废)取消
{
如果(!self.isComplete)
{
[自动定时器失效];
self.timer=nil;
self.isComplete=是;
NSError*cancelError=[NSError errorWithDomain:OD_AUTH_ERROR_域代码:ODAuthCanceled userInfo:@{}];
if(自我成功完成){
自我成功完成(无,取消错误);
}
}
}
-(无效)加载初始请求
{
[self.webView loadRequest:self.initialRequest];
}
-(void)重定向为startURL:(NSURL*)startURL
endURL:(NSURL*)endURL
成功:(ODEndURLCompletion)成功完成
{
self.endURL=endURL;
self.successCompletion=成功完成;
self.initialRequest=[nsurlRequestRequestWithURL:startURL];
self.isComplete=否;
[self.webView loadRequest:self.initialRequest];
}
-(void)负荷视图
{
self.webView=[[WKWebView alloc]init];
//Ern2[self.webView setScalesPageToFit:YES];
self.webView.autoresizingMask=uiviewsautoresizingflexiblewidth | uiviewsautoresizingflexiblewhight;
self.webView.navigationDelegate=self;//Ern2
self.view=self.webView;
UIBarButtonItem*cancel=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
目标:自我
操作:@选择器(取消)];
self.navigationController.topViewController.navigationItem.leftBarButtonItem=取消;
}
-(无效)视图将显示:(BOOL)动画
{
[超级视图将显示:动画];
[self.webView loadRequest:self.initialRequest];
}
-(无效)视图将消失:(BOOL)已设置动画
{
[self.webView停止加载];
self.webView.navigationDelegate=nil;
[超级视图将消失:动画];
}
#pragma标记-UI_WebViewDelegate
//Ern2
-(void)webView:(WKWebView*)webView didStartProvisionalNavigation:(null\u未指定的WKNavigation*)导航{
[自动定时器失效];
self.timer=[NSTimer scheduledTimerWithTimeInterval:self.requestTimeout目标:self选择器:@selector(failWithTimeout)userInfo:nil repeats:NO];
}
/*
-(void)webView下载:(UIWebVie_w*)webView
{
[自动定时器失效];
self.timer=[NSTimer scheduledTimerWithTimeInterval:self.requestTimeout目标:self选择器:@selector(failWithTimeout)userInfo:nil repeats:NO];
} */
-(void)webView:(WKWebView*)webView didFinishNavigation:(null_未指定的WKNavigation*)导航{
[自动定时器失效];
self.timer=nil;
}
/*
-(无效)webViewDidFinishLoad:(UIWebVie_w*)webView
{
[自动定时器失效];
self.timer=nil;
} */
-(void)webView:(WKWebView*)webView decisionpolicyfornavigationaction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler{
//NSLog(@“[ept]]@%@”,[navigationAction.request.URL absoluteString],[self.endURL absoluteString]);
if([[navigationAction.request.URL absoluteString]小写