iPhone address book imporovements: Make BusinessCardParsedResult more like Java version. Add AddressBookAUParser. Add more fields to MeCardParser. Fix order of parsers in UniversalResultParser.

git-svn-id: https://zxing.googlecode.com/svn/trunk@1860 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
gln@google.com 2011-07-15 20:32:27 +00:00
parent 1314542b1d
commit fdb0c30497
10 changed files with 345 additions and 79 deletions

View file

@ -23,23 +23,27 @@
#import "ParsedResult.h"
@interface BusinessCardParsedResult : ParsedResult {
NSString *name;
NSArray *names;
NSString *pronunciation;
NSArray *phoneNumbers;
NSArray *emails;
NSString *note;
NSString *email;
NSString *urlString;
NSString *address;
NSArray *addresses;
NSString *organization;
NSString *birthday;
NSString *jobTitle;
NSString *url;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, retain) NSArray *names;
@property (nonatomic, copy) NSString *pronunciation;
@property (nonatomic, retain) NSArray *phoneNumbers;
@property (nonatomic, retain) NSArray *emails;
@property (nonatomic, copy) NSString *note;
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString *urlString;
@property (nonatomic, copy) NSString *address;
@property (nonatomic, retain) NSArray *addresses;
@property (nonatomic, copy) NSString *organization;
@property (nonatomic, copy) NSString *birthday;
@property (nonatomic, copy) NSString *jobTitle;
@property (nonatomic, copy) NSString *url;
@end

View file

@ -1,5 +1,5 @@
//
// AddressBookDoCoMoParsedResult.m
// BusinesCardParsedResult.m
// ZXing
//
// Created by Christian Brunschen on 29/05/2008.
@ -22,71 +22,109 @@
#import "BusinessCardParsedResult.h"
#import "AddContactAction.h"
@interface BusinessCardParsedResult (Private)
- (void)append:(id)obj to:(NSMutableString *)dest;
+ (NSString *)normalizeName:(NSString*)name;
@end
@implementation BusinessCardParsedResult (Private)
// Append an object's string representation to dest preceeded by a newline. If
// it is an array, append each item sequentially.
- (void)append:(id)obj to:(NSMutableString *)dest {
if (obj == nil) {
return;
}
if ([obj isKindOfClass:[NSArray class]]) {
for (id sub in obj) {
[self append:sub to:dest];
}
} else if ([obj isKindOfClass:[NSString class]]) {
[dest appendFormat:@"\n%@", obj];
}
}
// Convert lastname,firstname to firstname lastname.
+ (NSString *)normalizeName:(NSString*)name {
int comma = [name rangeOfString:@","].location;
if (comma != NSNotFound) {
// Format may be last,first; switch it around
NSString* firstName = [name
substringWithRange:NSMakeRange(comma + 1,
[name length] - comma - 1)];
NSString* lastName = [name
substringWithRange:NSMakeRange(0, comma)];
return [NSString stringWithFormat:@"%@ %@", firstName, lastName];
}
return name;
}
@end
@implementation BusinessCardParsedResult
@synthesize name;
@synthesize names;
@synthesize pronunciation;
@synthesize phoneNumbers;
@synthesize emails;
@synthesize note;
@synthesize email;
@synthesize urlString;
@synthesize address;
@synthesize addresses;
@synthesize organization;
@synthesize birthday;
@synthesize jobTitle;
@synthesize url;
- (NSString *)stringForDisplay {
NSMutableString *result = [NSMutableString stringWithString:self.name];
if (self.jobTitle) [result appendFormat:@"\n%@",self.jobTitle];
if (self.organization) [result appendFormat:@"\n%@",self.organization];
if (self.phoneNumbers) {
for (NSString *number in self.phoneNumbers) {
[result appendFormat:@"\n%@", number];
NSMutableString* result = [NSMutableString stringWithCapacity:1024];
for (NSString *name in names) {
[self append:[BusinessCardParsedResult normalizeName:name] to:result];
}
}
if (self.email) {
[result appendFormat:@"\n%@", self.email];
}
if (self.urlString) {
[result appendFormat:@"\n%@", self.urlString];
}
if (self.note) {
[result appendFormat:@"\n%@", self.note];
}
if (self.address) {
[result appendFormat:@"\n%@", self.address];
}
return [NSString stringWithString:result];
[self append:pronunciation to:result];
[self append:jobTitle to:result];
[self append:organization to:result];
[self append:phoneNumbers to:result];
[self append:emails to:result];
[self append:url to:result];
[self append:birthday to:result];
[self append:note to:result];
[self append:addresses to:result];
return result;
}
- (void)populateActions {
[actions addObject:[AddContactAction actionWithName:self.name
phoneNumbers:self.phoneNumbers
email:self.email
url:self.urlString
address:self.address
note:self.note
organization:self.organization
jobTitle:self.jobTitle]];
[actions addObject:[AddContactAction actionWithName:[self.names objectAtIndex:0]
phoneNumbers:self.phoneNumbers
email:[self.emails objectAtIndex:0]
url:self.url
address:[self.addresses objectAtIndex:0]
note:self.note
organization:self.organization
jobTitle:self.jobTitle]];
}
- (void) dealloc {
[name release];
[phoneNumbers release];
[email release];
[urlString release];
[address release];
[note release];
[organization release];
[jobTitle release];
[super dealloc];
- (void)dealloc {
[names release];
[pronunciation release];
[phoneNumbers release];
[emails release];
[note release];
[addresses release];
[organization release];
[birthday release];
[jobTitle release];
[url release];
[super dealloc];
}
+ (NSString *)typeName {
return NSLocalizedString(@"Contact Result Type Name", @"Contact");
return NSLocalizedString(@"Contact Result Type Name", @"Contact");
}
- (UIImage *)icon {
return [UIImage imageNamed:@"business-card.png"];
return [UIImage imageNamed:@"business-card.png"];
}
@end

View file

@ -0,0 +1,31 @@
//
// AddressBookAUResultParser.h
// ZXing
//
// Created by George Nachman on 7/7/2011.
/*
* Copyright 2011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
#import "ResultParser.h"
@interface AddressBookAUResultParser : ResultParser {
}
@end

View file

@ -0,0 +1,122 @@
//
// AddressBookAUResultParser.m
// ZXing
//
// Ported to Objective-C by George Nachman on 7/7/2011.
/*
* Copyright 2011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "AddressBookAUResultParser.h"
#import "BusinessCardParsedResult.h"
#import "CBarcodeFormat.h"
#import "DoCoMoResultParser.h"
@interface NSString (AddressBookAUResultParser)
- (NSArray *)fieldsWithPrefix:(NSString *)prefix
maxResults:(int)maxResults
trim:(BOOL)trim;
@end
@implementation NSString (AddressBookAUResultParser)
- (NSArray *)fieldsWithPrefix:(NSString *)prefix
maxResults:(int)maxResults
trim:(BOOL)trim {
NSMutableArray *values = nil;
for (int i = 1; i <= maxResults; i++) {
NSString *prefixWithNum = [NSString stringWithFormat:@"%@%d:", prefix, i];
NSString *value = [self fieldWithPrefix:prefixWithNum
terminator:@"\r"];
if (value == nil) {
break;
}
if (trim) {
value = [value stringWithTrimmedWhitespace];
}
if (values == nil) {
values = [NSMutableArray arrayWithCapacity:maxResults];
}
[values addObject:value];
}
return values;
}
@end
@implementation AddressBookAUResultParser
+ (void)load {
[ResultParser registerResultParserClass:self];
}
//
// Implements KDDI AU's address book format. See
// http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html.
// (Thanks to Yuzo for translating!)
// Credit to Sean Owen as the original author of this class in Java.
//
+ (ParsedResult *)parsedResultForString:(NSString *)rawText
format:(BarcodeFormat)format {
// MEMORY is mandatory; seems like a decent indicator, as does
// end-of-record separator CR/LF
if (rawText == nil ||
[rawText rangeOfString:@"MEMORY"].location == NSNotFound ||
[rawText rangeOfString:@"\r\n"].location == NSNotFound) {
return nil;
}
// NAME1 and NAME2 have specific uses, namely written name and
// pronunciation, respectively. Therefore we treat them specially instead
// of as an array of names.
NSString *name = [[rawText fieldWithPrefix:@"NAME1:"
terminator:@"\r"] stringWithTrimmedWhitespace];
NSString *pronunciation =
[[rawText fieldWithPrefix:@"NAME2:"
terminator:@"\r"] stringWithTrimmedWhitespace];
NSArray *phoneNumbers =
[rawText fieldsWithPrefix:@"TEL"
maxResults:3
trim:YES];
NSArray *emails =
[rawText fieldsWithPrefix:@"MAIL"
maxResults:3
trim:YES];
NSString *note =
[rawText fieldWithPrefix:@"MEMORY:"
terminator:@"\r"];
NSString *address =
[[rawText fieldWithPrefix:@"ADD:"
terminator:@"\r"] stringWithTrimmedWhitespace];
NSArray *addresses = address ? [NSArray arrayWithObject:address] : nil;
BusinessCardParsedResult *result = [[BusinessCardParsedResult alloc] init];
result.names = [NSArray arrayWithStringIfNotNil:name];
result.pronunciation = pronunciation;
result.phoneNumbers = phoneNumbers;
result.emails = emails;
result.note = note;
result.addresses = addresses;
return [result autorelease];
}
@end

View file

@ -22,12 +22,20 @@
#import <UIKit/UIKit.h>
#import "ResultParser.h"
@interface NSString (DoCoMoFieldParsing)
@interface NSString (DoCoMoFieldParsing)
- (NSString *)backslashUnescaped;
- (NSArray *)fieldsWithPrefix:(NSString *)prefix;
- (NSArray *)fieldsWithPrefix:(NSString *)prefix terminator:(NSString *)term;
- (NSString *)fieldWithPrefix:(NSString *)prefix;
- (NSString *)fieldWithPrefix:(NSString *)prefix terminator:(NSString *)term;
- (NSString *)stringWithTrimmedWhitespace;
@end
@interface NSArray (DoCoMoStringArray)
- (NSArray*)stringArrayWithTrimmedWhitespace;
+ (NSArray*)arrayWithStringIfNotNil:(NSString *)string;
@end

View file

@ -29,7 +29,7 @@
if (backslashRange.location == NSNotFound) {
return self;
}
int max = [self length];
int startLocation = 0;
NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
@ -53,7 +53,7 @@
- (NSArray *)fieldsWithPrefix:(NSString *)prefix terminator:(NSString *)term {
NSMutableArray *result = nil;
int i = 0;
int max = [self length];
NSRange searchRange;
@ -65,7 +65,7 @@
if(foundRange.location == NSNotFound) {
break;
}
int start = i = foundRange.location + foundRange.length;
bool done = false;
while (!done) {
@ -93,7 +93,7 @@
}
}
[pool release];
return [result autorelease];
}
@ -110,6 +110,31 @@
}
}
- (NSString *)stringWithTrimmedWhitespace {
return [self stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
}
@end
@implementation NSArray (DoCoMoStringArray)
- (NSArray*)stringArrayWithTrimmedWhitespace {
NSMutableArray* trimmed = [NSMutableArray arrayWithCapacity:[self count]];
for (NSString* s in self) {
[trimmed addObject:[s stringWithTrimmedWhitespace]];
}
return trimmed;
}
+ (NSArray*)arrayWithStringIfNotNil:(NSString *)string {
if (string != nil) {
return [NSArray arrayWithObject:string];
} else {
return nil;
}
}
@end

View file

@ -23,6 +23,27 @@
#import "BusinessCardParsedResult.h"
#import "CBarcodeFormat.h"
@interface MeCardParser (Private)
+ (BOOL)isWellFormedBirthday:(NSString *)birthday;
@end
@implementation MeCardParser (Private)
+ (BOOL)isWellFormedBirthday:(NSString *)birthday {
if ([birthday length] != 8) {
return NO;
}
NSCharacterSet* nonDigits =
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789"]
invertedSet];
NSRange range = [birthday rangeOfCharacterFromSet:nonDigits];
return range.location == NSNotFound;
}
@end
@implementation MeCardParser
+ (void)load {
@ -36,22 +57,28 @@
return nil;
}
NSString *name = [s fieldWithPrefix:@"N:"];
NSString *name = [[s fieldWithPrefix:@"N:"] stringWithTrimmedWhitespace];
if (name == nil) {
return nil;
}
BusinessCardParsedResult *result = [[BusinessCardParsedResult alloc] init];
result.name = name;
result.phoneNumbers = [s fieldsWithPrefix:@"TEL:"];
result.email = [s fieldWithPrefix:@"EMAIL:"];
result.names = [NSArray arrayWithObject:name];
result.pronunciation = [[s fieldWithPrefix:@"SOUND:"] stringWithTrimmedWhitespace];
result.phoneNumbers = [[s fieldsWithPrefix:@"TEL:"] stringArrayWithTrimmedWhitespace];
result.emails = [[s fieldsWithPrefix:@"EMAIL:"] stringArrayWithTrimmedWhitespace];
result.note = [s fieldWithPrefix:@"NOTE:"];
result.urlString = [s fieldWithPrefix:@"URL:"];
result.address = [s fieldWithPrefix:@"ADR:"];
//The following tags are not stricty parot of MECARD spec, but as their are standard in
//vcard, we honor them
result.organization = [s fieldWithPrefix:@"ORG:"];
result.addresses = [[s fieldsWithPrefix:@"ADR:"] stringArrayWithTrimmedWhitespace];
result.birthday = [[s fieldWithPrefix:@"BDAY:"] stringWithTrimmedWhitespace];
if (result.birthday != nil && ![MeCardParser isWellFormedBirthday:result.birthday]) {
// No reason to throw out the whole card because the birthday is formatted wrong.
result.birthday = nil;
}
// The following tags are not stricty part of MECARD spec, but as they are standard in
// vcard, we honor them.
result.url = [[s fieldWithPrefix:@"URL:"] stringWithTrimmedWhitespace];
result.organization = [[s fieldWithPrefix:@"ORG:"] stringWithTrimmedWhitespace];
result.jobTitle = [s fieldWithPrefix:@"TITLE:"];
return [result autorelease];

View file

@ -58,8 +58,9 @@
normalizedProductID = s;
}
return [[ProductParsedResult alloc] initWithProductID:s
normalizedProductID:normalizedProductID];
return [[[ProductParsedResult alloc] initWithProductID:s
normalizedProductID:normalizedProductID]
autorelease];
}
@end

View file

@ -20,6 +20,7 @@
#import "TextResultParser.h"
#import "CBarcodeFormat.h"
#import "ProductResultParser.h"
#import "AddressBookAUResultParser.h"
@implementation UniversalResultParser
static NSMutableArray *sTheResultParsers = nil;
@ -41,16 +42,17 @@ static NSMutableArray *sTheResultParsers = nil;
}
}
[pool release];
[self addParserClass:[SMSResultParser class]];
[self addParserClass:[TelResultParser class]];
[self addParserClass:[SMSTOResultParser class]];
[self addParserClass:[MeCardParser class]];
[self addParserClass:[URLResultParser class]];
[self addParserClass:[URLTOResultParser class]];
[self addParserClass:[PlainEmailResultParser class]];
[self addParserClass:[EmailDoCoMoResultParser class]];
[self addParserClass:[BookmarkDoCoMoResultParser class]];
[self addParserClass:[MeCardParser class]];
[self addParserClass:[EmailDoCoMoResultParser class]];
[self addParserClass:[AddressBookAUResultParser class]];
[self addParserClass:[PlainEmailResultParser class]];
[self addParserClass:[TelResultParser class]];
[self addParserClass:[SMSResultParser class]];
[self addParserClass:[SMSTOResultParser class]];
[self addParserClass:[GeoResultParser class]];
[self addParserClass:[URLTOResultParser class]];
[self addParserClass:[URLResultParser class]];
[self addParserClass:[ProductResultParser class]];
[self addParserClass:[TextResultParser class]];
}

View file

@ -13,6 +13,8 @@
1DFA092513CE251600599044 /* ProductParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DFA092313CE251600599044 /* ProductParsedResult.m */; };
1DFA092A13CE252300599044 /* ProductResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DFA092813CE252300599044 /* ProductResultParser.h */; };
1DFA092B13CE252300599044 /* ProductResultParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1DFA092913CE252300599044 /* ProductResultParser.mm */; };
1DFA09A013CE5C0300599044 /* AddressBookAUResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DFA099E13CE5C0300599044 /* AddressBookAUResultParser.h */; };
1DFA09A113CE5C0300599044 /* AddressBookAUResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DFA099F13CE5C0300599044 /* AddressBookAUResultParser.m */; };
1F027FAB11A7BEAF006B06DE /* Decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F027F9F11A7BEAF006B06DE /* Decoder.h */; };
1F027FAC11A7BEAF006B06DE /* Decoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F027FA011A7BEAF006B06DE /* Decoder.mm */; };
1F027FAD11A7BEAF006B06DE /* DecoderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F027FA111A7BEAF006B06DE /* DecoderDelegate.h */; };
@ -248,6 +250,8 @@
1DFA092313CE251600599044 /* ProductParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ProductParsedResult.m; path = Classes/parsedResults/ProductParsedResult.m; sourceTree = "<group>"; };
1DFA092813CE252300599044 /* ProductResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProductResultParser.h; path = Classes/resultParsers/ProductResultParser.h; sourceTree = "<group>"; };
1DFA092913CE252300599044 /* ProductResultParser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ProductResultParser.mm; path = Classes/resultParsers/ProductResultParser.mm; sourceTree = "<group>"; };
1DFA099E13CE5C0300599044 /* AddressBookAUResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AddressBookAUResultParser.h; path = Classes/resultParsers/AddressBookAUResultParser.h; sourceTree = "<group>"; };
1DFA099F13CE5C0300599044 /* AddressBookAUResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AddressBookAUResultParser.m; path = Classes/resultParsers/AddressBookAUResultParser.m; sourceTree = "<group>"; };
1F027F9F11A7BEAF006B06DE /* Decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Decoder.h; path = Classes/Decoder.h; sourceTree = "<group>"; };
1F027FA011A7BEAF006B06DE /* Decoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Decoder.mm; path = Classes/Decoder.mm; sourceTree = "<group>"; };
1F027FA111A7BEAF006B06DE /* DecoderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DecoderDelegate.h; path = Classes/DecoderDelegate.h; sourceTree = "<group>"; };
@ -800,6 +804,8 @@
children = (
1FB4319D12901C76002D63E8 /* UniversalResultParser.h */,
1FB4319E12901C76002D63E8 /* UniversalResultParser.m */,
1DFA099E13CE5C0300599044 /* AddressBookAUResultParser.h */,
1DFA099F13CE5C0300599044 /* AddressBookAUResultParser.m */,
1F027FFB11A7BF06006B06DE /* BookmarkDoCoMoResultParser.h */,
1F027FFC11A7BF06006B06DE /* BookmarkDoCoMoResultParser.m */,
1F027FFD11A7BF06006B06DE /* DoCoMoResultParser.h */,
@ -1007,6 +1013,7 @@
1DFA090C13CE1A3900599044 /* CBarcodeFormat.h in Headers */,
1DFA092413CE251600599044 /* ProductParsedResult.h in Headers */,
1DFA092A13CE252300599044 /* ProductResultParser.h in Headers */,
1DFA09A013CE5C0300599044 /* AddressBookAUResultParser.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1173,6 +1180,7 @@
1DFA090D13CE1A3900599044 /* CBarcodeFormat.mm in Sources */,
1DFA092513CE251600599044 /* ProductParsedResult.m in Sources */,
1DFA092B13CE252300599044 /* ProductResultParser.mm in Sources */,
1DFA09A113CE5C0300599044 /* AddressBookAUResultParser.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};