【发布时间】:2016-05-20 04:46:41
【问题描述】:
如何解析 mailto 请求?
'mailto:someone@example.com?cc=someone_else@example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'
我想从这个 NSURL 中提取收件人、主题和正文。我该怎么办?
谢谢
【问题讨论】:
如何解析 mailto 请求?
'mailto:someone@example.com?cc=someone_else@example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'
我想从这个 NSURL 中提取收件人、主题和正文。我该怎么办?
谢谢
【问题讨论】:
这里有一些代码可以解析任何 URL 并返回一个字典,其中包含参数和字典中的相关对象。它也适用于mailto URL。
请注意:此代码假定您使用的是 ARC!
@interface NSString (URLDecoding)
- (NSString *) URLDecodedString;
@end
@implementation NSString (URLDecoding)
- (NSString *) URLDecodedString {
NSString *result = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (__bridge CFStringRef)self, CFSTR(""), kCFStringEncodingUTF8);
return result;
}
@end
- (NSDictionary *) parameterDictionaryFromURL:(NSURL *)url {
NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init];
if ([[url scheme] isEqualToString:@"mailto"]) {
NSString *mailtoParameterString = [[url absoluteString] substringFromIndex:[@"mailto:" length]];
NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:@"?"].location;
[parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:@"recipient"];
if (questionMarkLocation != NSNotFound) {
NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]];
}
}
}
else {
NSString *parameterString = [url parameterString];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]];
}
}
return [parameterDictionary copy];
}
这是你如何使用它的:
NSURL *mailtoURL = [NSURL URLWithString:@"mailto:foo@example.com?cc=bar@example.com&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!"];
NSDictionary *parameterDictionary = [self parameterDictionaryFromURL:mailtoURL];
NSString *recipient = [parameterDictionary objectForKey:@"recipient"];
NSString *subject = [parameterDictionary objectForKey:@"subject"];
NSString *body = [parameterDictionary objectForKey:@"body"];
编辑:
我更新了代码以使用任何 URL,并且收件人现在在 mailto URL 的字典中。
【讨论】:
我会像这样从中提取电子邮件:
NSString * mailToString = @"'mailto:someone@example.com?cc=someone_else@example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'";
NSArray *tempArray = [mailToString componentsSeparatedByString:@"?"];
//get email address from array
NSString * emailString = [[tempArray objectAtIndex:0]description];
//clean up string
emailString = [emailString stringByReplacingOccurrencesOfString:@"'mailto:" withString:@""];
//and here is your email string
NSLog(@"%@",emailString);
【讨论】:
-description 是非常糟糕的做法。
-description 是非常糟糕的做法?
从 iOS 7 开始,这可以通过 NSURLComponents 轻松实现。您可以使用以下命令创建该对象:
if let components = NSURLComponents(URL: url, resolvingAgainstBaseURL:false) { ...
然后就可以让接收者访问NSURLComponents的path属性了;以及带有 queryItems 属性的参数。例如,如果我们想要获取主题,这样的事情就可以完成我们的工作
let queryItems = components.queryItems as? [NSURLQueryItem]
let subject = queryItems?.filter({$0.name == "subject"}).first?.value
【讨论】:
queryItems 和 NSURLQueryItem 类本身仅在 iOS 8.0 之后才可用。
仅用于 mailto 的 NSURL 类别:此方法还修复了上面 Fabian 的答案中的崩溃错误,当时 mailto: url 不包含?。它也不需要 URLDecodedString 类别方法。
@implementation NSURL (Additions)
- (NSDictionary *) parameterDictionaryForMailTo {
NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init];
NSString *mailtoParameterString = [[self absoluteString] substringFromIndex:[@"mailto:" length]];
NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:@"?"].location;
if (questionMarkLocation != NSNotFound) {
[parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:@"recipient"];
NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1];
NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"];
for (NSString *queryString in keyValuePairs) {
NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="];
if (keyValuePair.count == 2)
[parameterDictionary setObject:[[keyValuePair objectAtIndex:1] stringByRemovingPercentEncoding] forKey:[[keyValuePair objectAtIndex:0] stringByRemovingPercentEncoding]];
}
}
else {
[parameterDictionary setObject:mailtoParameterString forKey:@"recipient"];
}
return [parameterDictionary copy];
}
【讨论】: