Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@
INFOPLIST_FILE = "$(SRCROOT)/WebView Demo for iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "WebView Demo for iOS";
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
Expand All @@ -278,7 +278,7 @@
INFOPLIST_FILE = "$(SRCROOT)/WebView Demo for iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "WebView Demo for iOS";
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
Expand Down
7 changes: 7 additions & 0 deletions Demos/WebView Demo for iOS/WebView Demo for iOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,12 @@
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ <h3>Top Sites</h3>
<li><a href="https://www.google.co.uk/maps/place/Grand+Canyon,+Arizona,+USA/@36.1099945,-112.9425755,9z/data=!3m1!4b1!4m2!3m1!1s0x80ccbe8deef948db:0xb27cc01c5959c8d2">Local Canyons</a></li>
<li><a href="http://en.wikipedia.org/wiki/Geococcyx">Geococcyx on Wikipedia</a></li>
<li><a href="https://mobile.twitter.com/session/new">Twitter</a></li>
<li><a href="https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr">Facebook</a></li>
<li><a href="https://facebook.com/">Facebook</a></li>
</ol>

<div id="bottom"></div>
Expand Down
58 changes: 24 additions & 34 deletions OnePasswordExtension.m
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ - (void)changePasswordForLoginForURLString:(nonnull NSString *)URLString loginDe
- (void)fillItemIntoWebView:(nonnull id)webView forViewController:(nonnull UIViewController *)viewController sender:(nullable id)sender showOnlyLogins:(BOOL)yesOrNo completion:(nullable void (^)(BOOL success, NSError * __nullable error))completion {
NSAssert(webView != nil, @"webView must not be nil");
NSAssert(viewController != nil, @"viewController must not be nil");
NSAssert([webView isKindOfClass:[UIWebView class]] || [webView isKindOfClass:[WKWebView class]], @"webView must be an instance of WKWebView or UIWebView.");

#ifdef __IPHONE_8_0
if ([webView isKindOfClass:[UIWebView class]]) {
Expand All @@ -217,18 +218,15 @@ - (void)fillItemIntoWebView:(nonnull id)webView forViewController:(nonnull UIVie
}
}];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
else if ([webView isKindOfClass:[WKWebView class]]) {
[self fillItemIntoWKWebView:webView forViewController:viewController sender:(id)sender showOnlyLogins:yesOrNo completion:^(BOOL success, NSError *error) {
if (completion) {
completion(success, error);
}
}];
}
#endif
else {
[NSException raise:@"Invalid argument: web view must be an instance of WKWebView or UIWebView." format:@""];
}
#endif
#endif
}

Expand All @@ -240,15 +238,16 @@ - (BOOL)isOnePasswordExtensionActivityType:(nullable NSString *)activityType {

- (void)createExtensionItemForWebView:(nonnull id)webView completion:(void (^)(NSExtensionItem * __nullable extensionItem, NSError * __nullable error))completion {
NSAssert(webView != nil, @"webView must not be nil");

NSAssert([webView isKindOfClass:[UIWebView class]] || [webView isKindOfClass:[WKWebView class]], @"webView must be an instance of WKWebView or UIWebView.");

#ifdef __IPHONE_8_0
if ([webView isKindOfClass:[UIWebView class]]) {
UIWebView *uiWebView = (UIWebView *)webView;
NSString *collectedPageDetails = [uiWebView stringByEvaluatingJavaScriptFromString:OPWebViewCollectFieldsScript];

[self createExtensionItemForURLString:uiWebView.request.URL.absoluteString webPageDetails:collectedPageDetails completion:completion];
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
else if ([webView isKindOfClass:[WKWebView class]]) {
WKWebView *wkWebView = (WKWebView *)webView;
[wkWebView evaluateJavaScript:OPWebViewCollectFieldsScript completionHandler:^(NSString *result, NSError *evaluateError) {
Expand All @@ -272,10 +271,7 @@ - (void)createExtensionItemForWebView:(nonnull id)webView completion:(void (^)(N
[self createExtensionItemForURLString:wkWebView.URL.absoluteString webPageDetails:result completion:completion];
}];
}
#endif
else {
[NSException raise:@"Invalid argument: web view must be an instance of WKWebView or UIWebView." format:@""];
}
#endif
#endif
}

Expand Down Expand Up @@ -385,7 +381,7 @@ - (void)findLoginIn1PasswordWithURLString:(NSString *)URLString collectedPageDet
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
- (void)fillItemIntoWKWebView:(WKWebView *)webView forViewController:(UIViewController *)viewController sender:(id)sender showOnlyLogins:(BOOL)yesOrNo completion:(void (^)(BOOL success, NSError *error))completion {
- (void)fillItemIntoWKWebView:(nonnull WKWebView *)webView forViewController:(nonnull UIViewController *)viewController sender:(nullable id)sender showOnlyLogins:(BOOL)yesOrNo completion:(void (^)(BOOL success, NSError * __nullable error))completion {
[webView evaluateJavaScript:OPWebViewCollectFieldsScript completionHandler:^(NSString *result, NSError *error) {
if (result == nil) {
NSLog(@"1Password Extension failed to collect web page fields: %@", error);
Expand All @@ -405,7 +401,7 @@ - (void)fillItemIntoWKWebView:(WKWebView *)webView forViewController:(UIViewCont
}
#endif

- (void)fillItemIntoUIWebView:(UIWebView *)webView webViewController:(UIViewController *)viewController sender:(id)sender showOnlyLogins:(BOOL)yesOrNo completion:(void (^)(BOOL success, NSError *error))completion {
- (void)fillItemIntoUIWebView:(nonnull UIWebView *)webView webViewController:(nonnull UIViewController *)viewController sender:(nullable id)sender showOnlyLogins:(BOOL)yesOrNo completion:(void (^)(BOOL success, NSError * __nullable error))completion {
NSString *collectedPageDetails = [webView stringByEvaluatingJavaScriptFromString:OPWebViewCollectFieldsScript];
[self findLoginIn1PasswordWithURLString:webView.request.URL.absoluteString collectedPageDetails:collectedPageDetails forWebViewController:viewController sender:sender withWebView:webView showOnlyLogins:yesOrNo completion:^(BOOL success, NSError *error) {
if (completion) {
Expand All @@ -414,7 +410,8 @@ - (void)fillItemIntoUIWebView:(UIWebView *)webView webViewController:(UIViewCont
}];
}

- (void)executeFillScript:(NSString *)fillScript inWebView:(id)webView completion:(void (^)(BOOL success, NSError *error))completion {
- (void)executeFillScript:(NSString * __nullable)fillScript inWebView:(nonnull id)webView completion:(void (^)(BOOL success, NSError * __nullable error))completion {

if (fillScript == nil) {
NSLog(@"Failed to executeFillScript, fillScript is missing");
if (completion) {
Expand All @@ -427,6 +424,7 @@ - (void)executeFillScript:(NSString *)fillScript inWebView:(id)webView completio
NSMutableString *scriptSource = [OPWebViewFillScript mutableCopy];
[scriptSource appendFormat:@"(document, %@);", fillScript];

#ifdef __IPHONE_8_0
if ([webView isKindOfClass:[UIWebView class]]) {
NSString *result = [((UIWebView *)webView) stringByEvaluatingJavaScriptFromString:scriptSource];
BOOL success = (result != nil);
Expand All @@ -440,12 +438,10 @@ - (void)executeFillScript:(NSString *)fillScript inWebView:(id)webView completio
if (completion) {
completion(success, error);
}

return;
}

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
if ([webView isKindOfClass:[WKWebView class]]) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 || ONE_PASSWORD_EXTENSION_ENABLE_WK_WEB_VIEW
else if ([webView isKindOfClass:[WKWebView class]]) {
[((WKWebView *)webView) evaluateJavaScript:scriptSource completionHandler:^(NSString *result, NSError *evaluationError) {
BOOL success = (result != nil);
NSError *error = nil;
Expand All @@ -459,16 +455,13 @@ - (void)executeFillScript:(NSString *)fillScript inWebView:(id)webView completio
completion(success, error);
}
}];

return;
}
#endif
#endif

[NSException raise:@"Invalid argument: web view must be an instance of WKWebView or UIWebView." format:@""];
}

#ifdef __IPHONE_8_0
- (void)processExtensionItem:(NSExtensionItem *)extensionItem completion:(void (^)(NSDictionary *itemDictionary, NSError *error))completion {
- (void)processExtensionItem:(nullable NSExtensionItem *)extensionItem completion:(void (^)(NSDictionary *itemDictionary, NSError * __nullable error))completion {
if (extensionItem.attachments.count == 0) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: @"Unexpected data returned by App Extension: extension item had no attachments." };
NSError *error = [[NSError alloc] initWithDomain:AppExtensionErrorDomain code:AppExtensionErrorCodeUnexpectedData userInfo:userInfo];
Expand Down Expand Up @@ -509,12 +502,9 @@ - (void)processExtensionItem:(NSExtensionItem *)extensionItem completion:(void (
}];
}

- (UIActivityViewController *)activityViewControllerForItem:(NSDictionary *)item viewController:(UIViewController*)viewController sender:(id)sender typeIdentifier:(NSString *)typeIdentifier {
- (UIActivityViewController *)activityViewControllerForItem:(nonnull NSDictionary *)item viewController:(nonnull UIViewController*)viewController sender:(nullable id)sender typeIdentifier:(nonnull NSString *)typeIdentifier {
#ifdef __IPHONE_8_0

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && sender == nil) {
[NSException raise:@"Invalid argument: sender must not be nil on iPad." format:@""];
}
NSAssert(NO == (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && sender == nil), @"sender must not be nil on iPad.");

NSItemProvider *itemProvider = [[NSItemProvider alloc] initWithItem:item typeIdentifier:typeIdentifier];

Expand Down Expand Up @@ -542,7 +532,7 @@ - (UIActivityViewController *)activityViewControllerForItem:(NSDictionary *)item

#endif

- (void)createExtensionItemForURLString:(NSString *)URLString webPageDetails:(NSString *)webPageDetails completion:(void (^)(NSExtensionItem *extensionItem, NSError *error))completion {
- (void)createExtensionItemForURLString:(nonnull NSString *)URLString webPageDetails:(nullable NSString *)webPageDetails completion:(void (^)(NSExtensionItem *extensionItem, NSError * __nullable error))completion {
NSError *jsonError = nil;
NSData *data = [webPageDetails dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *webPageDetailsDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
Expand Down Expand Up @@ -587,7 +577,7 @@ + (NSError *)extensionCancelledByUserError {
return [NSError errorWithDomain:AppExtensionErrorDomain code:AppExtensionErrorCodeCancelledByUser userInfo:userInfo];
}

+ (NSError *)failedToContactExtensionErrorWithActivityError:(NSError *)activityError {
+ (NSError *)failedToContactExtensionErrorWithActivityError:(nullable NSError *)activityError {
NSMutableDictionary *userInfo = [NSMutableDictionary new];
userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"Failed to contact the 1Password Extension", @"OnePasswordExtension", @"1Password Extension Error Message");
if (activityError) {
Expand All @@ -597,7 +587,7 @@ + (NSError *)failedToContactExtensionErrorWithActivityError:(NSError *)activityE
return [NSError errorWithDomain:AppExtensionErrorDomain code:AppExtensionErrorCodeFailedToContactExtension userInfo:userInfo];
}

+ (NSError *)failedToCollectFieldsErrorWithUnderlyingError:(NSError *)underlyingError {
+ (NSError *)failedToCollectFieldsErrorWithUnderlyingError:(nullable NSError *)underlyingError {
NSMutableDictionary *userInfo = [NSMutableDictionary new];
userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"Failed to execute script that collects web page information", @"OnePasswordExtension", @"1Password Extension Error Message");
if (underlyingError) {
Expand All @@ -607,7 +597,7 @@ + (NSError *)failedToCollectFieldsErrorWithUnderlyingError:(NSError *)underlying
return [NSError errorWithDomain:AppExtensionErrorDomain code:AppExtensionErrorCodeCollectFieldsScriptFailed userInfo:userInfo];
}

+ (NSError *)failedToFillFieldsErrorWithLocalizedErrorMessage:(NSString *)errorMessage underlyingError:(NSError *)underlyingError {
+ (NSError *)failedToFillFieldsErrorWithLocalizedErrorMessage:(nullable NSString *)errorMessage underlyingError:(nullable NSError *)underlyingError {
NSMutableDictionary *userInfo = [NSMutableDictionary new];
if (errorMessage) {
userInfo[NSLocalizedDescriptionKey] = errorMessage;
Expand All @@ -619,7 +609,7 @@ + (NSError *)failedToFillFieldsErrorWithLocalizedErrorMessage:(NSString *)errorM
return [NSError errorWithDomain:AppExtensionErrorDomain code:AppExtensionErrorCodeFillFieldsScriptFailed userInfo:userInfo];
}

+ (NSError *)failedToLoadItemProviderDataErrorWithUnderlyingError:(NSError *)underlyingError {
+ (NSError *)failedToLoadItemProviderDataErrorWithUnderlyingError:(nullable NSError *)underlyingError {
NSMutableDictionary *userInfo = [NSMutableDictionary new];
userInfo[NSLocalizedDescriptionKey] = NSLocalizedStringFromTable(@"Failed to parse information returned by 1Password Extension", @"OnePasswordExtension", @"1Password Extension Error Message");
if (underlyingError) {
Expand Down