iOS 手机常见功能总结(一)

文章目录

    • 一:打电话
        • 1、旧的API :openURL
        • 2、新的API : openURL:url options: completionHandler:
        • 附 :
        • 3、利用WebView吊起电话
          • 3.1 UIWebView
          • 3.2 WKWebView
    • 二:发短信
        • 1、使用openURL
          • 1.1 直接唤起短信功能,不预设值短信内容
          • 1.2 唤起短信功能,预设置短信内容
        • 2、使用MessageUI框架
    • 三、发邮件
        • 1、使用openURL
          • 1.1 直接唤起邮箱,不预设置邮件内容
          • 1.2 唤起邮箱功能,预设置邮件内容
        • 2、使用MessageUI框架
    • 四、获取通讯录联系人信息
        • 1、Contact 一键大法,无感获取通讯录所有联系人信息
        • 2、ContactUI 有感获取,你想要我我愿给的

前言 常见的那些功能,其实经常用不到,但是用到的时候又是经常用的到,总结一下,以免一时脑子瓦特想不起来

一:打电话

随着API的更新,打电话的方式也在改变

1、旧的API :openURL

- (void)callType01 {
    NSURL *url = [NSURL URLWithString:@"tel://10086"];
    if ([[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"tel://"]]) {
        BOOL result = [[UIApplication sharedApplication]openURL:url];
        NSLog(@"%d",result);
    }
}

简述:该api在iOS10.0被弃用
iOS9.0以前,打电话前没有弹窗提示、通话结束后不能返回到app;
在iOS10.2以前,打电话前没有弹窗提示;
在10.2.1开始,有弹窗提示。
返回指是一个BOOL类型,通过返回值来判断呼叫状态

2、新的API : openURL:url options: completionHandler:

- (void)callType02 {
    NSURL *url = [NSURL URLWithString:@"tel://10086"];
    if ([[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"tel://"]]) {
        [[UIApplication sharedApplication]openURL:url options:@{} completionHandler:nil];
    }
}

简述:iOS10.0之后的新API
iOS10.2之前,没有弹窗提示,之后有弹窗提示,结束之后能返回到当前app
completionHandler返回值能获得呼叫状态

附 :

在旧的API中,部分版本没吊起电话前没有弹窗提示,这会引起误操作呼叫电话,造成不必要的麻烦,所以会使用

NSURL *url =[NSURL URLWithString:@“telprompt://10000”];

把@“tel://” 修改成@“telprompt://”,这样在呼叫之前就会有弹窗提示;但是从后续的API发展看,apple似乎也注意到了直接呼出没有弹窗提示的弊端,这不符合苹果的安全意识逻辑,后续的系统版本陆续加上弹窗提示,所以再没必要这么使用了,而且这么使用可能会引起上架审核失败,所以仅限于了解便可

3、利用WebView吊起电话

3.1 UIWebView
- (void)callType03 {
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"tel://10010"]]];
    [self.view addSubview:webView];
}

简述 :版本的分界线已经不清楚了,用的12的版本测试在呼叫之前是有弹窗提示的,在iOS 13之后,官方建议别再使用UIWebView,所以新的项目还是尽量去使用WKWebView去处理

3.2 WKWebView
- (void)webView:(WKWebView *)webView
    decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
                    decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
                    
    NSURL *url = navigationAction.request.URL;
    NSString *scheme = [url scheme];
    UIApplication *app = [UIApplication sharedApplication];
    // 打电话
    if ([scheme isEqualToString:@"tel"]) {
        if ([app canOpenURL:url]) {
            if (@available(iOS 10.0, *)) {
                [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
            } else {
                [[UIApplication sharedApplication] openURL:url];
            }
            decisionHandler(WKNavigationActionPolicyCancel);
            return;
        }
    }
 }

简述 : 在- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction;方法中去实现

二:发短信

1、使用openURL

1.1 直接唤起短信功能,不预设值短信内容
if ([[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"SMS://"]] ) {
        NSURL *url = [NSURL URLWithString:@"sms://10000"];
        if (@available(iOS 10.0, *)) {
            [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
        } else {
            [[UIApplication sharedApplication] openURL:url];
        }
    }

直接唤起短信页面,不预设置短信内容,短信发送完成或者取消发送后留在短信页面,不返回当前app

1.2 唤起短信功能,预设置短信内容
NSString *phoneStr = [NSString stringWithFormat:@"10010"];//发短信的号码
    NSString *smsContentStr = [NSString stringWithFormat:@"喵,我不想你只是情不自已的想给你发个短信。汪"];
    NSString *urlStr = [NSString stringWithFormat:@"sms://%@&body=%@", phoneStr, smsContentStr];
    // 需要处理中文
    urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; 
    NSURL *url = [NSURL URLWithString:urlStr];
    if (@available(iOS 10.0, *)) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }

直接唤起短信页面,预设置短信内容,短信发送完成或者取消发送后留在短信页面,不返回当前app

目前测试,该方式发送短信只识别第一个号码;如果传入一组号码,以","分割,依然是只识别第一个号码,并小概率引起短息编辑页面bug,取消编辑按钮失效,编辑页面无法退出。所以群发还没处理方式,或者说我个人还没找到这种方法下的群发操作。

2、使用MessageUI框架

同时遵守协议,设置代理,协议方法中可以监听短信的发送状态(枚举)MessageComposeResult

- (void)SMS02 {
    // 判断短信功能是否可用
    if (![MFMessageComposeViewController canSendText]) {
        NSLog(@"小主!您的设备不能发送短信~");
        return;
    }
    
    MFMessageComposeViewController * controller = [[MFMessageComposeViewController alloc] init];
    // 数组的形式加入多个号码
    controller.recipients = @[@"10010", @"10000"];
    // 预设置短信内容
    controller.body = @"汪,下午三点的月亮真的好漂亮。喵";
    controller.messageComposeDelegate = self;
    [self presentViewController:controller animated:YES completion:nil];
}
#pragma mark - MFMessageComposeViewControllerDelegate
-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
    [self dismissViewControllerAnimated:YES completion:nil];
    switch (result) {
        case MessageComposeResultSent:
            NSLog(@"发送成功");
            break;
        case MessageComposeResultFailed:
            NSLog(@"发送失败");
            break;
        case MessageComposeResultCancelled:
            NSLog(@"取消发送");
            break;
        default:
            break;
    }
}

直接唤起短信页面,预设置短信内容,短信发送完成或者取消发送后返回当前app,能够群发短信

三、发邮件

1、使用openURL

1.1 直接唤起邮箱,不预设置邮件内容

附:前面也介绍了openURL和openURL: options: completionHandler: 的区别,当今版本,已经到iOS 13以上了,微信都不兼容太低的系统版本,加上写个人写的demo是从iOS11开始,故之后的demo对部分兼容低版本的不在体现在代码中。

if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"mailto://"]]) {
        NSLog(@"小主!您的设备不能发送邮件~");
        return;
    }
    NSURL *url = [NSURL URLWithString:@"mailto:[email protected]"];
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];

直接唤起邮箱页面,不预设置邮件内容,邮件发送完成或者取消发送后留在邮箱,不返回当前app

1.2 唤起邮箱功能,预设置邮件内容
NSMutableString *mailUrl = [[NSMutableString alloc]init];
    // 添加收件人
    NSArray *toRecipients = [NSArray arrayWithObjects:@"[email protected]", @"[email protected]", nil];
    [mailUrl appendFormat:@"mailto:%@", [toRecipients componentsJoinedByString:@","]];
    // 添加抄送对象
    NSArray *ccRecipients = [NSArray arrayWithObjects:@"[email protected]", nil];
    [mailUrl appendFormat:@"?cc=%@", [ccRecipients componentsJoinedByString:@","]];
    // 添加密对象
    NSArray *bccRecipients = [NSArray arrayWithObjects:@"[email protected]", nil];
    [mailUrl appendFormat:@"&bcc=%@", [bccRecipients componentsJoinedByString:@","]];
    // 设置主题
    [mailUrl appendString:@"&subject=致喵和汪"];
    // 设置邮件内容
    [mailUrl appendString:@"&body=请别再见面就打架了,谢谢 \n--局外人!"];
    NSString* email = [mailUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    // 发送
    [[UIApplication sharedApplication] openURL: [NSURL URLWithString:email] options:@{} completionHandler:nil];

直接唤起邮箱页面,预设置邮件内容,邮件发送完成或者取消发送后留在邮箱,不返回当前app

2、使用MessageUI框架

- (void)email02 {
    if (![MFMailComposeViewController canSendMail]) {
        NSLog(@"小主!您的设备不能发送邮件~");
        return;
    }
    MFMailComposeViewController *mailCompose = [[MFMailComposeViewController alloc] init];
    mailCompose.mailComposeDelegate = self;
    // 设置主题
    [mailCompose setSubject: @"致喵和汪"];
    // 添加收件人
    NSArray *toRecipients = [NSArray arrayWithObjects:@"[email protected]", @"[email protected]", nil];
    [mailCompose setToRecipients: toRecipients];
    // 添加抄送对象
    NSArray *ccRecipients = [NSArray arrayWithObjects:@"[email protected]", @"[email protected]", nil];
    [mailCompose setCcRecipients:ccRecipients];
    // 添加密对象
    NSArray *bccRecipients = [NSArray arrayWithObjects:@"[email protected]", nil];
    [mailCompose setBccRecipients:bccRecipients];
    // 邮件添加图片内容
    UIImage *addPic = [UIImage imageNamed: @"protait"];
    NSData *imageData = UIImagePNGRepresentation(addPic);
    // mineType 设置不同的附件内容 如图片、pdf文件、视频等 :https://www.iana.org/assignments/media-types/media-types.xhtml
    [mailCompose addAttachmentData:imageData mimeType:@"image" fileName:@"pic.png"];
    // 设置邮件主题:isHTML-> YES:富文本  NO:字符串
    NSString *emailBody = @"喵、汪~ \n请别再见面就打架了,谢谢 \n--局外人!";
    [mailCompose setMessageBody:emailBody isHTML:YES];
    [self presentViewController:mailCompose animated:NO completion:nil];
}

#pragma mark - MFMailComposeViewControllerDelegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    [controller dismissViewControllerAnimated:YES completion:nil];
    switch (result) {
        case MFMailComposeResultCancelled:
            NSLog(@"取消编辑");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"保存邮件");
            break;
        case MFMailComposeResultSent:
            NSLog(@"用户已发送,邮件进入发送队列");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"保存/发送失败");
            break;
        default:
            break;
    }
}

直接唤起邮件页面,预设置邮件内容,邮件发送完成或者取消发送后返回当前app,能够群发邮件

四、获取通讯录联系人信息

iOS 9之前的旧框架AddressBookUI和AddressBook就不在这谈及了,谈谈iOS 9之后的新框架ContactsUI和Contacts
#import

1、Contact 一键大法,无感获取通讯录所有联系人信息

- (void)conctact01 {
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status == CNAuthorizationStatusNotDetermined) {
        CNContactStore *store = [[CNContactStore alloc] init];
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError*  _Nullable error) {
            if (error) {
                NSLog(@"你没有获取用户联系人列表权限");
            } else {
                [self infoLost];
            }
        }];
    } else if(status == CNAuthorizationStatusRestricted) {
        NSLog(@"你没有获取用户联系人列表权限");
    } else if (status == CNAuthorizationStatusDenied) {
        NSLog(@"你没有获取用户联系人列表权限");
    } else if (status == CNAuthorizationStatusAuthorized) {
        [self infoLost];
    }
}

/// 所有电话号码 无情丢失
- (void)infoLost {
    NSArray *keysToFetch = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
    CNContactFetchRequest *fetchRequest = [[CNContactFetchRequest alloc] initWithKeysToFetch:keysToFetch];
    CNContactStore *contactStore = [[CNContactStore alloc] init];
    
    [contactStore enumerateContactsWithFetchRequest:fetchRequest error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        // 姓名
        NSString * familyName = contact.familyName;
        NSString * givenName = contact.givenName;
        // 电话
        NSArray * phoneNums = contact.phoneNumbers;
        CNLabeledValue *labelValue = phoneNums.firstObject;  // 选取第一个电话
        NSString *phoneValue = [labelValue.value stringValue];
        NSLog(@"姓名:%@%@ 电话:%@", familyName, givenName, phoneValue);
    }];
}

该方式只提供联系人信息,没有UI界面,想要界面可以自己搭建,或者用ContactUI的方式,在使用之前申请使用通讯录权限。

附:骚一句
我以为那些在我手机里的是我的秘密,没想到它只是皇帝的新装

2、ContactUI 有感获取,你想要我我愿给的

- (void)conctact02 {
    _contactPickerViewController = [[CNContactPickerViewController alloc]init];
    _contactPickerViewController.delegate = self;
    [self presentViewController:_contactPickerViewController animated:YES completion:nil];
}

#pragma mark - CNContactPickerDelegate
/// 取消事件
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
    NSLog(@"contactPickerDidCancel - %@", picker);
}

/// 从通讯录直接获取联系人
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
    // 姓名
    NSString * familyName = contact.familyName;
    NSString * givenName = contact.givenName;
    // 电话
    NSArray * phoneNums = contact.phoneNumbers;
    CNLabeledValue *labelValue = phoneNums.firstObject;  // 选取第一个电话
    NSString *phoneValue = [labelValue.value stringValue];
    NSLog(@"姓名:%@%@ 电话:%@", familyName, givenName, phoneValue);
}

///  到联系人主页获取联系人
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty {
    // 姓名
    NSString * familyName = contactProperty.contact.familyName;
    NSString * givenName = contactProperty.contact.givenName;
    // 电话
    NSString * phoneNum = [contactProperty.value stringValue];
    NSLog(@"姓名:%@%@ 电话:%@  -- %@", familyName, givenName, phoneNum, contactProperty.contact.phoneNumbers);
}

///  在通讯录同时选取多个联系人,点击完成按钮,获得多个联系人信息
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContacts:(NSArray<CNContact*> *)contacts {
    for (CNContact * contact in contacts) {
        // 姓名
        NSString * familyName = contact.familyName;
        NSString * givenName = contact.givenName;
        // 电话
        NSArray * phoneNums = contact.phoneNumbers;
        CNLabeledValue *labelValue = phoneNums.firstObject;  // 选取第一个电话
        NSString *phoneValue = [labelValue.value stringValue];
        NSLog(@"姓名:%@%@ 电话:%@", familyName, givenName, phoneValue);
    }
}
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperties:(NSArray<CNContactProperty*> *)contactProperties {

}

需要设置代理CNContactPickerDelegate,在代理的几个方法中需要,获取联系人信息的四个方法需要单独使用,根据需求去选择,因为不同的代理方法,在通讯录页面的展示和选择方式不一样

你可能感兴趣的:(iOS-OC)