簡體   English   中英

iOS OneDrive SDK - 需要更新已棄用的 UIWebView

[英]iOS OneDrive SDK - needs update for deprecated UIWebView

OneDriveSDK for iOS 有一段時間沒有更新,並使用已棄用的 UIWebView 登錄。Apple 將停止接受使用 UIWebView 的應用程序。 因為我們不知道 Microsoft 是否/何時會更新此 SDK,所以我想分享我使用 WKWebView 進行的代碼更改。

這個解決方案現在已經過時了。 不要使用。


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

請參閱下面的代碼。
我在我更新的地方添加了評論“ern2”。

在 ADAL 目標/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

“已接受”的答案現在已經過時,因為您不應該再使用舊的 OneDrive pod。

OneDrive API for iOS 確實讓我對缺乏簡單的說明和設置感到沮喪。 微軟的主要演示頁面甚至不再鏈接到 iOS 示例(至少對於我發現的)。

您需要使用 GRAPH api。 ObjC Graph pod 似乎已經過時,不確定是否/何時會更新。

MSAL 是用於向 Microsoft/Graph 進行身份驗證的身份驗證庫。 這是用 ObjC 編寫的。 沒問題。 這是最新的並保持不變。 用這個。

沒有來自 Microsoft 的 Graph/OneDrive API pod 的問題(除非您想使用“舊”的)意味着您需要自己弄清楚所有調用,並進行低級別的 GET/PUT/POST 調用,並找出網址。 有點麻煩。

以下是我發現有用的鏈接:

僅使用 MSAL cocoapod 的示例 swift 代碼。 我喜歡這個,因為干凈; 不使用舊 Graph API,它自 2015 年以來尚未更新,還沒有 1.0 版。 缺點是您必須弄清楚自己的 URL 調用,但示例包括演示調用https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-ios

另一個較舊的教程。 存檔的教程頁面(下面的鏈接)有一些我覺得有用的設置細節,以補充上面的演示。 上面的演示可能是您所需要的,但我首先發現了這個演示,並且一些與 MSAL 設置相關的說明很有幫助。 使用“過時”(?)ObjC Graph API cocoapod https://github.com/microsoftgraph/msgraph-training-ios-swift/tree/main/tutorial

OneDrive 圖 API 信息: https://docs.microsoft.com/en-us/onedrive/developer/rest-api/?view=odsp-graph-online

一般圖表信息: https://docs.microsoft.com/en-us/graph/use-the-api

查詢參數: https://docs.microsoft.com/en-us/graph/query-parameters

分頁: https://docs.microsoft.com/en-us/graph/paging

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM