blob: 583674eb9de058a0fcaa3e9b0c077e59f49ee1f6 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/download/vcard_coordinator.h"
#include <ContactsUI/ContactsUI.h>
#include "base/scoped_observation.h"
#import "ios/chrome/browser/download/vcard_tab_helper.h"
#import "ios/chrome/browser/download/vcard_tab_helper_delegate.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/web_state_list/web_state_dependency_installer_bridge.h"
#import "ios/web/public/web_state_observer_bridge.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface VcardCoordinator () <DependencyInstalling, VcardTabHelperDelegate> {
// Bridge which observes WebStateList and alerts this coordinator when this
// needs to register the Mediator with a new WebState.
std::unique_ptr<WebStateDependencyInstallerBridge> _dependencyInstallerBridge;
}
// NavigationController that contains a viewController used to display a
// contact.
@property(nonatomic, strong) UINavigationController* navigationViewController;
@end
@implementation VcardCoordinator
- (instancetype)initWithBaseViewController:(UIViewController*)baseViewController
browser:(Browser*)browser {
if (self = [super initWithBaseViewController:baseViewController
browser:browser]) {
_dependencyInstallerBridge =
std::make_unique<WebStateDependencyInstallerBridge>(
self, browser->GetWebStateList());
}
return self;
}
- (void)stop {
// Reset this observer manually. We want this to go out of scope now, to
// ensure it detaches before `browser` and its WebStateList get destroyed.
_dependencyInstallerBridge.reset();
self.navigationViewController = nil;
}
#pragma mark - DependencyInstalling methods
- (void)installDependencyForWebState:(web::WebState*)webState {
if (VcardTabHelper::FromWebState(webState)) {
VcardTabHelper::FromWebState(webState)->set_delegate(self);
}
}
- (void)uninstallDependencyForWebState:(web::WebState*)webState {
if (VcardTabHelper::FromWebState(webState)) {
VcardTabHelper::FromWebState(webState)->set_delegate(nil);
}
}
#pragma mark - Private
// Dismisses the the `navigationViewController`.
- (void)dismissButtonTapped {
[self.baseViewController dismissViewControllerAnimated:true completion:nil];
}
// Retreives contact informations from `data` and presents it.
- (void)presentContactVCardFromData:(NSData*)vcardData {
// TODO(crbug.com/1278657): Vcard download code only support the first
// contact.
CNContact* contact =
[[CNContactVCardSerialization contactsWithData:vcardData
error:nil] firstObject];
if (!contact) {
return;
}
CNContactViewController* contactViewController =
[CNContactViewController viewControllerForUnknownContact:contact];
contactViewController.allowsEditing = YES;
contactViewController.contactStore = [[CNContactStore alloc] init];
UIBarButtonItem* dismissButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(dismissButtonTapped)];
contactViewController.navigationItem.leftBarButtonItem = dismissButton;
self.navigationViewController = [[UINavigationController alloc]
initWithRootViewController:contactViewController];
[self.baseViewController presentViewController:self.navigationViewController
animated:YES
completion:nil];
}
#pragma mark - VcardTabHelperDelegate
- (void)openVcardFromData:(NSData*)vcardData {
DCHECK(vcardData);
[self presentContactVCardFromData:vcardData];
}
@end