Detect the “access code” portion of a conference c

2019-08-13 17:21发布

问题:

Given an EKEvent that represents a calendar entry on an iOS device, I'm trying to detect not only a phone number but also the related conference call access code.

For example, given:

NSString *text = @"Blah Blah Blah (555) 123-4567 Access Code: 9876# Blah Blah Blah";

I'd like to implement a method that would return this value:

@"555-123-4567,,9876#"

Calendar entries might use various text besides @"Access Code: " to describe the number used to access a conference call. For example, other strings might include @"passcode: ", @"virtual room number: ", etc.

I am aware of NSDataDetector's ability to detect a phone number, but given the above example string, it returns @"555-123-4567 Access Code: 9876#" (note that 'Access Code' is still a substring here).

I'm thinking about just taking the value returned from NSDataDetector and doing a string replacement for @"Access Code: " and similar substrings that might appear on a calendar entry, replacing with @",,", but this doesn't seem sufficiently elegant. I'd prefer for the NSDataDetector to do this for me.

Here is my code that I'm not super happy with:

- (NSArray *) phonesFromText:(NSString *)text {
    NSMutableArray *phones = [NSMutableArray array];

    if (text) {
        NSError *error = nil;
        NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber
                                                                   error:&error];

        [detector enumerateMatchesInString:text
                                   options:kNilOptions
                                     range:NSMakeRange(0, [text length])
                                usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                                    NSString *phoneNumberWithText = result.phoneNumber;

                                    // Replace "access code:" with ",," so that it can be dialed by the built-in phone app
                                    NSString *phoneNumberWithoutText = [phoneNumberWithText stringByReplacingOccurrencesOfString:@"access code:"
                                                                                                                      withString:@",,"
                                                                                                                         options:NSCaseInsensitiveSearch
                                                                                                                           range:NSMakeRange(0, [phoneNumberWithText length])];

                                    // Remove any unwanted characters that may still be lingering after the above string replacement
                                    NSCharacterSet * toRemove = [[NSCharacterSet characterSetWithCharactersInString:@"+,#-0123456789"] invertedSet];
                                    phoneNumberWithoutText = [[phoneNumberWithoutText componentsSeparatedByCharactersInSet:toRemove] componentsJoinedByString:@""];                                        

                                    [phones addObject:phoneNumberWithoutText];
                                }];

    }

    return phones;
}

Question: Other than the string replacement solution that I proposed above, is there a better way to do this?