I have experience with Java and Android development, and am now attempting to learn Objective-C and iPhone/iPad development. In order to help teach myself, I am re-writing an application I made for android over to iPhone.
The specific problem I am having has to do with using the NSScanner class. In my android application, I read in a txt file(with multiple lines) and built "member" objects that get loaded into an array. Each member has general contact info being a first name, last name, phone number, email, pledge class and major. This text file was written by me so I know the exact formatting. Below is an example of one line in the text file.
Fawzy Jake 8144425471 [email protected] Beta Criminal Justice & Psych Minor
In Java/android I was able to load the desired results by using multiple scan.Next() and then a scan.nextLine() for the major. Can anyone help point me in the right direction of how to use NSScanner/objective-c to perform a similar operation? Specifically, I would like to know how to properly scan through the text file/string, then build my member object with the information I grabbed from the string.
Below is an example of my code that I have been working on, but am having trouble putting what I want to do logically into syntax as I am not familiar with objective-c.
- (NSString *)loadFileToString{
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"akpsi_contact_list"
ofType:@"txt"];
NSError *error = nil;
NSString *fileContent = [NSString stringWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:&error];
if(error)
{
NSLog(@"ERROR while loading from file: %@", error);
}
return fileContent;
}
-(void)readFileString{
NSScanner *scanner = [NSScanner scannerWithString: self.loadFileToString];
while ([scanner isAtEnd] == NO) {
//member object
AKPsiMember *member;
//temporary variables
NSString *thisFirstName;
NSString *thisLastName;
NSString *thisPhoneNum;
NSString *thisEmail;
NSString *thisPledge;
NSString *thisMajor;
//scan one line, save
[scanner scanUpToString:@" " intoString:&thisFirstName];
[scanner scanUpToString:@" " intoString:&thisLastName];
[scanner scanUpToString:@" " intoString:&thisPhoneNum];
[scanner scanUpToString:@" " intoString:&thisEmail];
[scanner scanUpToString:@" " intoString:&thisPledge];
[scanner scanUpToString:@" " intoString:&thisMajor];
//build member object with temporary variables
// implementation must continue to next line...
}
}
Also my member object/class
.h
@interface AKPsiMember : NSObject{
NSString *firstName;
NSString *lastName;
NSString *emailAddress;
NSString *pledgeClass;
NSString *major;
NSString *phoneNum;
}
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *emailAddress;
@property (nonatomic, strong) NSString *pledgeClass;
@property (nonatomic, strong) NSString *major;
@property (nonatomic, strong) NSString *phoneNum;
@end
And my .m
@implementation AKPsiMember
@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@synthesize phoneNum = _phoneNum;
@synthesize emailAddress = _emailAddress;
@synthesize pledgeClass = _pledgeClass;
@synthesize major = _major;
- (NSString *)phoneNum:(NSNumber *)num
{
if(num == 0)
{
NSString *temp1 = [self.phoneNum substringWithRange:NSMakeRange(0, 3)];
NSString *temp2 = [self.phoneNum substringWithRange:NSMakeRange(3, 6)];
NSString *temp3 = [self.phoneNum substringWithRange:NSMakeRange(6, 9)];
NSString *formatNum = [NSString stringWithFormat: @"(%@) %@-%@", temp1, temp2, temp3];
return formatNum;
}
else{
return self.phoneNum;
}
}
@end
After you scanned all your fields you should scan the newline character in order to proceed to the next line:
NSCharacterSet *whitespace = [NSCharacterSet whitespaceCharacterSet];
[scanner scanUpToCharactersFromSet:whitespace intoString:&thisFirstName];
[scanner scanCharactersFromSet:whitespace intoString:nil];
[scanner scanUpToCharactersFromSet:whitespace intoString:&thisLastName];
[scanner scanCharactersFromSet:whitespace intoString:nil];
[scanner scanUpToCharactersFromSet:whitespace intoString:&thisPhoneNum];
[scanner scanCharactersFromSet:whitespace intoString:nil];
[scanner scanUpToCharactersFromSet:whitespace intoString:&thisEmail];
[scanner scanCharactersFromSet:whitespace intoString:nil];
[scanner scanUpToCharactersFromSet:whitespace intoString:&thisPledge];
[scanner scanCharactersFromSet:whitespace intoString:nil];
NSCharacterSet *newLineCharacterSet = [NSCharacterSet newlineCharacterSet];
[scanner scanUpToCharactersFromSet:newLineCharacterSet intoString:&thisMajor];
[scanner scanCharactersFromSet:newLineCharacterSet intoString:nil];
Create the NSMutableArray before the loop.
NSMutableArray *members = [NSMutableArray array];
Set the values inside the loop and add your Object to the members array.
AKPsiMember *member = [[AKPsiMember alloc] init];
member.firstName = thisFirstName;
// ... set other properties
[members addObject:member];
This code will break when there are whitespaces in between the first fields of your dataset. Obviously this could be broken down into methods and results should be checked.