shlist

share and manage lists between multiple people
Log | Files | Refs

commit 973662d4dabe1457d952a0ce2856eddec1dc6a01
parent cbfc0317e04e6684218991e3a251547e1d00cd77
Author: Kyle Milz <kyle@Kyles-MacBook-Pro.local>
Date:   Wed,  9 Sep 2015 23:22:08 -0600

ios-ng: add address book lookup

Diffstat:
Mios-ng/NewItemTableViewController.m | 80++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mios-ng/shlist.xcodeproj/project.pbxproj | 38++++++++++++++++----------------------
Aios-ng/shlist/AddressBook.h | 7+++++++
Aios-ng/shlist/AddressBook.m | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mios-ng/shlist/Base.lproj/Main.storyboard | 244++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mios-ng/shlist/ListDetailTableViewController.m | 24+++++++++++++++++-------
Mios-ng/shlist/SharedListsTableViewController.m | 3+++
Mios-ng/shlist/ShlistServer.m | 160+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
8 files changed, 452 insertions(+), 210 deletions(-)

diff --git a/ios-ng/NewItemTableViewController.m b/ios-ng/NewItemTableViewController.m @@ -6,6 +6,13 @@ @implementation NewItemTableViewController +// called when shared switch is toggled +- (IBAction)shared_switch:(id)sender +{ + // hide/unhide the shared status group + [self.tableView reloadData]; +} + - (void)viewDidLoad { [super viewDidLoad]; @@ -23,27 +30,74 @@ #pragma mark - Table view data source -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { -#warning Potentially incomplete method implementation. - // Return the number of sections. - return 0; +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + // get the shared switch state to see if the shared properties should + // be shown + NSIndexPath *index_path = [NSIndexPath indexPathForRow:1 inSection:0]; + + UITableViewCell *cell = [super tableView:tableView + cellForRowAtIndexPath:index_path]; + + UISwitch *shared_switch = (UISwitch *)[cell viewWithTag:1]; + + if (shared_switch.isOn) { + return 2; + } else { + return 1; + } } -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { -#warning Incomplete method implementation. - // Return the number of rows in the section. - return 0; +- (NSInteger)tableView:(UITableView *)tableView + numberOfRowsInSection:(NSInteger)section +{ + + // NSLog(@"info: reloading rows in table view"); + + if (section == 0) + return 3; + else if (section == 1) + return 2; + + return 0; } -/* -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; +- (UITableViewCell *)tableView:(UITableView *)tableView + cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + //UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath]; // Configure the cell... - return cell; + //return cell; + + UITableViewCell *cell = [super tableView:tableView + cellForRowAtIndexPath:indexPath]; + // cell.accessoryType = UITableViewCellAccessoryNone; + + // NSUInteger section = [indexPath section]; + // NSUInteger row = [indexPath row]; + + /* + switch (section) + { + case SECTION_SPEED: + if (row == self.speed) + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + break; + + case SECTION_VOLUME: + if (row == self.volume) + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + break; + } + */ + return cell; } -*/ /* // Override to support conditional editing of the table view. diff --git a/ios-ng/shlist.xcodeproj/project.pbxproj b/ios-ng/shlist.xcodeproj/project.pbxproj @@ -23,11 +23,9 @@ 27C70F301B33F4FA00DADEB3 /* SharedListsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C70F2F1B33F4FA00DADEB3 /* SharedListsTableViewController.m */; }; 27C70F321B3650CB00DADEB3 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 27C70F311B3650CB00DADEB3 /* libsqlite3.dylib */; }; 27C70F351B36513200DADEB3 /* DBManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C70F341B36513200DADEB3 /* DBManager.m */; }; - 27DCC9DC1B8A96A900207340 /* dollar103.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9DB1B8A96A900207340 /* dollar103.png */; }; 27DCC9DE1B8A98D400207340 /* dollar103-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9DD1B8A98D400207340 /* dollar103-2.png */; }; - 27DCC9E01B8A993300207340 /* dollar103-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9DF1B8A993300207340 /* dollar103-3.png */; }; - 27DCC9E21B8A9A6900207340 /* dollar103-4.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9E11B8A9A6900207340 /* dollar103-4.png */; }; - 27DCC9E41B8A9EBB00207340 /* information15-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9E31B8A9EBB00207340 /* information15-2.png */; }; + 27DCC9E81B9EB4E800207340 /* information15-3.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9E71B9EB4E800207340 /* information15-3.png */; }; + 27DCC9EB1B9FF89E00207340 /* AddressBook.m in Sources */ = {isa = PBXBuildFile; fileRef = 27DCC9EA1B9FF89E00207340 /* AddressBook.m */; }; BF7776B91B38928D00526CB0 /* ListDetailTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BF7776B81B38928D00526CB0 /* ListDetailTableViewController.m */; }; BF7776BC1B38D0DB00526CB0 /* ListItem.m in Sources */ = {isa = PBXBuildFile; fileRef = BF7776BB1B38D0DB00526CB0 /* ListItem.m */; }; /* End PBXBuildFile section */ @@ -71,11 +69,10 @@ 27C70F311B3650CB00DADEB3 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; 27C70F331B36513200DADEB3 /* DBManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBManager.h; sourceTree = "<group>"; }; 27C70F341B36513200DADEB3 /* DBManager.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = DBManager.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; }; - 27DCC9DB1B8A96A900207340 /* dollar103.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dollar103.png; path = ../../../Downloads/dollar103.png; sourceTree = "<group>"; }; 27DCC9DD1B8A98D400207340 /* dollar103-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dollar103-2.png"; path = "../../../Downloads/dollar103-2.png"; sourceTree = "<group>"; }; - 27DCC9DF1B8A993300207340 /* dollar103-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dollar103-3.png"; path = "../../../Downloads/dollar103-3.png"; sourceTree = "<group>"; }; - 27DCC9E11B8A9A6900207340 /* dollar103-4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dollar103-4.png"; path = "../../../Downloads/dollar103-4.png"; sourceTree = "<group>"; }; - 27DCC9E31B8A9EBB00207340 /* information15-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "information15-2.png"; path = "../../../Downloads/information15-2.png"; sourceTree = "<group>"; }; + 27DCC9E71B9EB4E800207340 /* information15-3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "information15-3.png"; path = "../../../Downloads/information15-3.png"; sourceTree = "<group>"; }; + 27DCC9E91B9FF89E00207340 /* AddressBook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddressBook.h; sourceTree = "<group>"; }; + 27DCC9EA1B9FF89E00207340 /* AddressBook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddressBook.m; sourceTree = "<group>"; }; BF7776B71B38928D00526CB0 /* ListDetailTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListDetailTableViewController.h; sourceTree = "<group>"; }; BF7776B81B38928D00526CB0 /* ListDetailTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ListDetailTableViewController.m; sourceTree = "<group>"; }; BF7776BA1B38D0DB00526CB0 /* ListItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListItem.h; sourceTree = "<group>"; }; @@ -133,28 +130,27 @@ 27C70F011B32AF8000DADEB3 /* shlist */ = { isa = PBXGroup; children = ( + 27DCC9E91B9FF89E00207340 /* AddressBook.h */, + 27DCC9EA1B9FF89E00207340 /* AddressBook.m */, 27C70F061B32AF8000DADEB3 /* AppDelegate.h */, 27C70F071B32AF8000DADEB3 /* AppDelegate.m */, 27B039FD1B43B6830054B6D2 /* ContactsViewController.h */, 27B039FE1B43B6830054B6D2 /* ContactsViewController.m */, - 27C70F0C1B32AF8000DADEB3 /* Main.storyboard */, - 27DCC9DB1B8A96A900207340 /* dollar103.png */, + 27DCC9DD1B8A98D400207340 /* dollar103-2.png */, + 27C70F0F1B32AF8000DADEB3 /* Images.xcassets */, + 27DCC9E71B9EB4E800207340 /* information15-3.png */, + 27C70F111B32AF8000DADEB3 /* LaunchScreen.xib */, BF7776B71B38928D00526CB0 /* ListDetailTableViewController.h */, BF7776B81B38928D00526CB0 /* ListDetailTableViewController.m */, - 27DCC9E31B8A9EBB00207340 /* information15-2.png */, - 27DCC9E11B8A9A6900207340 /* dollar103-4.png */, - 27DCC9DF1B8A993300207340 /* dollar103-3.png */, - 27DCC9DD1B8A98D400207340 /* dollar103-2.png */, BF7776BA1B38D0DB00526CB0 /* ListItem.h */, BF7776BB1B38D0DB00526CB0 /* ListItem.m */, - 27C70F2E1B33F4FA00DADEB3 /* SharedListsTableViewController.h */, - 27C70F2F1B33F4FA00DADEB3 /* SharedListsTableViewController.m */, + 27C70F0C1B32AF8000DADEB3 /* Main.storyboard */, 27C70F2B1B33F3C300DADEB3 /* NewListViewController.h */, 27C70F2C1B33F3C300DADEB3 /* NewListViewController.m */, 27C70F281B33CE2500DADEB3 /* SharedList.h */, 27C70F291B33D1C900DADEB3 /* SharedList.m */, - 27C70F0F1B32AF8000DADEB3 /* Images.xcassets */, - 27C70F111B32AF8000DADEB3 /* LaunchScreen.xib */, + 27C70F2E1B33F4FA00DADEB3 /* SharedListsTableViewController.h */, + 27C70F2F1B33F4FA00DADEB3 /* SharedListsTableViewController.m */, 27C70F021B32AF8000DADEB3 /* Supporting Files */, ); path = shlist; @@ -268,11 +264,8 @@ buildActionMask = 2147483647; files = ( 27C70F0E1B32AF8000DADEB3 /* Main.storyboard in Resources */, - 27DCC9E41B8A9EBB00207340 /* information15-2.png in Resources */, 27C70F131B32AF8000DADEB3 /* LaunchScreen.xib in Resources */, - 27DCC9E21B8A9A6900207340 /* dollar103-4.png in Resources */, - 27DCC9E01B8A993300207340 /* dollar103-3.png in Resources */, - 27DCC9DC1B8A96A900207340 /* dollar103.png in Resources */, + 27DCC9E81B9EB4E800207340 /* information15-3.png in Resources */, 27C70F101B32AF8000DADEB3 /* Images.xcassets in Resources */, 27DCC9DE1B8A98D400207340 /* dollar103-2.png in Resources */, ); @@ -301,6 +294,7 @@ 27C70F2D1B33F3C300DADEB3 /* NewListViewController.m in Sources */, 27C70F081B32AF8000DADEB3 /* AppDelegate.m in Sources */, 27B039FF1B43B6830054B6D2 /* ContactsViewController.m in Sources */, + 27DCC9EB1B9FF89E00207340 /* AddressBook.m in Sources */, 27C70F301B33F4FA00DADEB3 /* SharedListsTableViewController.m in Sources */, 27C70F051B32AF8000DADEB3 /* main.m in Sources */, ); diff --git a/ios-ng/shlist/AddressBook.h b/ios-ng/shlist/AddressBook.h @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +@interface AddressBook : NSObject + +@property NSMutableDictionary *name_map; + +@end diff --git a/ios-ng/shlist/AddressBook.m b/ios-ng/shlist/AddressBook.m @@ -0,0 +1,105 @@ +#import "AddressBook.h" +#include <AddressBook/AddressBook.h> +#import <UIKit/UIKit.h> + + +@implementation AddressBook + +- (id)init +{ + self = [super init]; + if (self) + { + ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus(); + + if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) { + // if you got here, user had previously denied/revoked permission for your + // app to access the contacts, and all you can do is handle this gracefully, + // perhaps telling the user that they have to go to settings to grant access + // to contacts + + [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + return self; + } + + CFErrorRef error = NULL; + ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); + + if (!addressBook) { + NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error)); + return self; + } + + ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { + if (error) { + NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error)); + } + + if (granted) { + // if they gave you permission, then just carry on + + [self listPeopleInAddressBook:addressBook]; + } else { + // however, if they didn't give you permission, handle it gracefully, for example... + + dispatch_async(dispatch_get_main_queue(), ^{ + // BTW, this is not on the main thread, so dispatch UI updates back to the main queue + + [[[UIAlertView alloc] initWithTitle:nil message:@"This app requires access to your contacts to function properly. Please visit to the \"Privacy\" section in the iPhone Settings app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; + }); + } + + CFRelease(addressBook); + }); + } + return self; +} + +- (void)listPeopleInAddressBook:(ABAddressBookRef)addressBook +{ + NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); + NSInteger numberOfPeople = [allPeople count]; + + _name_map = [NSMutableDictionary dictionaryWithCapacity:numberOfPeople]; + + for (NSInteger i = 0; i < numberOfPeople; i++) { + ABRecordRef person = (__bridge ABRecordRef)allPeople[i]; + + NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty)); + // NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty)); + // NSLog(@"Name:%@ %@", firstName, lastName); + + ABMultiValueRef phoneNumbers = ABRecordCopyValue(person, kABPersonPhoneProperty); + + if (firstName == nil) { + // if we don't have a first name then we can't display it + continue; + } + + CFIndex numberOfPhoneNumbers = ABMultiValueGetCount(phoneNumbers); + for (CFIndex i = 0; i < numberOfPhoneNumbers; i++) { + NSString *phoneNumber = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phoneNumbers, i)); + + if (phoneNumber == nil) { + // if we have a name but no phone number, there's + // nothing we can do + continue; + } + + phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@" " withString:@""]; + phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@"(" withString:@""]; + phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@")" withString:@""]; + phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@"-" withString:@""]; + + [_name_map setObject:firstName forKey:phoneNumber]; + + // NSLog(@" phone:%@", phoneNumber); + } + + CFRelease(phoneNumbers); + + // NSLog(@"============================================="); + } +} + +@end +\ No newline at end of file diff --git a/ios-ng/shlist/Base.lproj/Main.storyboard b/ios-ng/shlist/Base.lproj/Main.storyboard @@ -64,7 +64,7 @@ </constraints> </tableViewCellContentView> <connections> - <segue destination="2Mz-oY-P1s" kind="show" id="3ew-8g-3Od"/> + <segue destination="8Gi-Gc-mRg" kind="show" id="u9Y-bO-Pfj"/> </connections> </tableViewCell> </prototypes> @@ -84,48 +84,144 @@ </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="H64-xB-1er" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="1188" y="-70"/> + <point key="canvasLocation" x="1172" y="-270"/> </scene> <!--Add Item--> <scene sceneID="OeV-vW-TVD"> <objects> <tableViewController title="Add Item" id="8Gi-Gc-mRg" customClass="NewItemTableViewController" sceneMemberID="viewController"> - <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="sGb-Al-WmL"> + <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="sGb-Al-WmL"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> - <prototypes> - <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="hpv-Jh-N2Z"> - <autoresizingMask key="autoresizingMask"/> - <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hpv-Jh-N2Z" id="bBG-J9-Qvq"> - <autoresizingMask key="autoresizingMask"/> - <subviews> - <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="2XT-Rw-cxe"> - <rect key="frame" x="8" y="7" width="97" height="30"/> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <textInputTraits key="textInputTraits"/> - </textField> - </subviews> - </tableViewCellContentView> - </tableViewCell> - <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="40G-4d-KXw"> - <autoresizingMask key="autoresizingMask"/> - <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="40G-4d-KXw" id="xcB-Zu-7Yt"> - <autoresizingMask key="autoresizingMask"/> - <subviews> - <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="CA8-dS-VRO"> - <rect key="frame" x="543" y="6" width="51" height="31"/> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Item is shared" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MsQ-Iq-XOk"> - <rect key="frame" x="8" y="11" width="108" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> - <nil key="highlightedColor"/> - </label> - </subviews> - </tableViewCellContentView> - </tableViewCell> - </prototypes> + <sections> + <tableViewSection headerTitle="Item Details" id="2DB-BM-NLj"> + <cells> + <tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="hpv-Jh-N2Z"> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hpv-Jh-N2Z" id="bBG-J9-Qvq"> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Name" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GRs-CY-ps2"> + <rect key="frame" x="8" y="11" width="46" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="&lt;item name&gt;" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RxZ-xc-Qog"> + <rect key="frame" x="466" y="11" width="101" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <constraints> + <constraint firstItem="RxZ-xc-Qog" firstAttribute="trailing" secondItem="bBG-J9-Qvq" secondAttribute="trailingMargin" id="Eg4-rr-HNe"/> + <constraint firstAttribute="centerY" secondItem="RxZ-xc-Qog" secondAttribute="centerY" id="J7h-Uo-2Vv"/> + </constraints> + </tableViewCellContentView> + </tableViewCell> + <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="40G-4d-KXw"> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="40G-4d-KXw" id="xcB-Zu-7Yt"> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Shared" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="MsQ-Iq-XOk"> + <rect key="frame" x="8" y="11" width="55" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + </label> + <switch opaque="NO" tag="1" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xy3-L7-YrZ"> + <rect key="frame" x="543" y="6" width="51" height="31"/> + <connections> + <action selector="shared_switch:" destination="8Gi-Gc-mRg" eventType="valueChanged" id="Add-PE-NRp"/> + </connections> + </switch> + </subviews> + <constraints> + <constraint firstItem="xy3-L7-YrZ" firstAttribute="trailing" secondItem="xcB-Zu-7Yt" secondAttribute="trailingMargin" id="JoL-Hq-y2d"/> + <constraint firstAttribute="centerY" secondItem="xy3-L7-YrZ" secondAttribute="centerY" id="yuO-MF-KCL"/> + </constraints> + </tableViewCellContentView> + </tableViewCell> + <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="EtU-pb-OGN"> + <rect key="frame" x="0.0" y="0.0" width="320" height="44"/> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="EtU-pb-OGN" id="rFW-W4-rEL"> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="ZG9-yz-YFh"> + <rect key="frame" x="543" y="6" width="51" height="31"/> + </switch> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Needs purchase" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Uxj-my-Z2Y"> + <rect key="frame" x="8" y="11" width="126" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <constraints> + <constraint firstAttribute="centerY" secondItem="ZG9-yz-YFh" secondAttribute="centerY" id="80p-g3-bEH"/> + <constraint firstItem="ZG9-yz-YFh" firstAttribute="trailing" secondItem="rFW-W4-rEL" secondAttribute="trailingMargin" id="vZc-93-inJ"/> + </constraints> + </tableViewCellContentView> + </tableViewCell> + </cells> + </tableViewSection> + <tableViewSection headerTitle="Shared Status" id="Lg0-Eo-t0T"> + <cells> + <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="CLf-ge-Fs1"> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="CLf-ge-Fs1" id="bPK-KB-4tb"> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Owner" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T4L-tN-tX4"> + <rect key="frame" x="8" y="11" width="51" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="&lt;persons name&gt;" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Y92-Cj-Q4R"> + <rect key="frame" x="462" y="11" width="130" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <constraints> + <constraint firstAttribute="centerY" secondItem="Y92-Cj-Q4R" secondAttribute="centerY" id="aQV-Ex-gn9"/> + <constraint firstItem="Y92-Cj-Q4R" firstAttribute="trailing" secondItem="bPK-KB-4tb" secondAttribute="trailingMargin" id="yHe-aI-QkZ"/> + </constraints> + </tableViewCellContentView> + </tableViewCell> + <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="aur-Cc-cv0"> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="aur-Cc-cv0" id="l74-H8-N2N"> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Cost" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Boa-7b-ddO"> + <rect key="frame" x="8" y="11" width="37" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="&lt;cost&gt;" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QhL-xd-rVc"> + <rect key="frame" x="538" y="11" width="54" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <constraints> + <constraint firstItem="QhL-xd-rVc" firstAttribute="trailing" secondItem="l74-H8-N2N" secondAttribute="trailingMargin" id="bNe-Ou-GSy"/> + <constraint firstAttribute="centerY" secondItem="QhL-xd-rVc" secondAttribute="centerY" id="sZa-du-szj"/> + </constraints> + </tableViewCellContentView> + </tableViewCell> + </cells> + </tableViewSection> + </sections> <connections> <outlet property="dataSource" destination="8Gi-Gc-mRg" id="v6S-Tx-yoO"/> <outlet property="delegate" destination="8Gi-Gc-mRg" id="tyD-6N-VIH"/> @@ -147,7 +243,7 @@ <placeholder placeholderIdentifier="IBFirstResponder" id="HuD-ay-3nZ" userLabel="First Responder" sceneMemberID="firstResponder"/> <exit id="lUt-lN-Y7n" userLabel="Exit" sceneMemberID="exit"/> </objects> - <point key="canvasLocation" x="2798" y="-225"/> + <point key="canvasLocation" x="1967" y="61"/> </scene> <!--Lists--> <scene sceneID="hc1-Lv-WtP"> @@ -187,7 +283,7 @@ <segue destination="pMK-tA-j4s" kind="show" identifier="show list segue" id="ORk-KR-Twe"/> </connections> </tableViewCell> - <tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="IndirectListPrototypeCell" textLabel="WuW-Sd-sxB" detailTextLabel="rf3-DG-Fgi" style="IBUITableViewCellStyleSubtitle" id="kbj-EX-eeF"> + <tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="IndirectListPrototypeCell" textLabel="WuW-Sd-sxB" detailTextLabel="rf3-DG-Fgi" style="IBUITableViewCellStyleSubtitle" id="kbj-EX-eeF"> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="kbj-EX-eeF" id="fgg-hw-Da6"> <autoresizingMask key="autoresizingMask"/> @@ -290,48 +386,6 @@ </objects> <point key="canvasLocation" x="2044" y="811"/> </scene> - <!--About Us--> - <scene sceneID="noJ-Ez-70t"> - <objects> - <viewController id="FlT-Xw-f5e" userLabel="About Us" sceneMemberID="viewController"> - <layoutGuides> - <viewControllerLayoutGuide type="top" id="3hJ-K1-i1o"/> - <viewControllerLayoutGuide type="bottom" id="9zw-4a-J6h"/> - </layoutGuides> - <view key="view" contentMode="scaleToFill" id="BEH-Qp-ix3"> - <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vqD-fu-CUL"> - <rect key="frame" x="16" y="57" width="568" height="316"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - <string key="text">This project is a humble attempt to help people be more organized. It's main purpose is to make group events easy to plan and execute. It's founders hope you find it as useful as they do.

This is something we do on our free time. If you respect that, please donate.</string> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> - </textView> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="About Us" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hjG-BQ-XBF"> - <rect key="frame" x="16" y="28" width="72" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> - <nil key="highlightedColor"/> - </label> - </subviews> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - <constraints> - <constraint firstItem="9zw-4a-J6h" firstAttribute="top" secondItem="vqD-fu-CUL" secondAttribute="bottom" constant="178" id="9Cp-IX-R3d"/> - <constraint firstItem="vqD-fu-CUL" firstAttribute="leading" secondItem="hjG-BQ-XBF" secondAttribute="leading" id="XeA-5Y-GFI"/> - <constraint firstItem="vqD-fu-CUL" firstAttribute="top" secondItem="hjG-BQ-XBF" secondAttribute="bottom" constant="8" symbolic="YES" id="ZQH-f4-CgD"/> - <constraint firstItem="hjG-BQ-XBF" firstAttribute="leading" secondItem="BEH-Qp-ix3" secondAttribute="leadingMargin" id="dS7-kL-9Vc"/> - <constraint firstItem="hjG-BQ-XBF" firstAttribute="top" secondItem="3hJ-K1-i1o" secondAttribute="bottom" constant="8" symbolic="YES" id="nss-ZG-IMi"/> - <constraint firstItem="vqD-fu-CUL" firstAttribute="trailing" secondItem="BEH-Qp-ix3" secondAttribute="trailingMargin" id="rlU-s2-Y9s"/> - </constraints> - </view> - <tabBarItem key="tabBarItem" title="About Us" id="djS-DN-skn" userLabel="About Us"/> - </viewController> - <placeholder placeholderIdentifier="IBFirstResponder" id="BxS-VD-IQ2" userLabel="First Responder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="292" y="-1628"/> - </scene> <!--Contacts--> <scene sceneID="QO3-Nz-2Rw"> <objects> @@ -364,7 +418,6 @@ <connections> <segue destination="0GJ-5e-Vr4" kind="relationship" relationship="viewControllers" id="nLJ-0v-l7T"/> <segue destination="U8c-wO-OWj" kind="relationship" relationship="viewControllers" id="Tf1-0f-ulH"/> - <segue destination="FlT-Xw-f5e" kind="relationship" relationship="viewControllers" id="Hqb-Fa-lrf"/> </connections> </tabBarController> <placeholder placeholderIdentifier="IBFirstResponder" id="PWN-St-ASU" userLabel="First Responder" sceneMemberID="firstResponder"/> @@ -424,33 +477,10 @@ </navigationController> <placeholder placeholderIdentifier="IBFirstResponder" id="AR0-99-D0J" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="1973" y="-524"/> - </scene> - <!--Edit List Item--> - <scene sceneID="aq6-TL-408"> - <objects> - <tableViewController title="Edit List Item" id="2Mz-oY-P1s" sceneMemberID="viewController"> - <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="0da-SL-Cmm"> - <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> - <prototypes> - <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="s9f-Ak-39U"> - <autoresizingMask key="autoresizingMask"/> - <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="s9f-Ak-39U" id="Ozs-uw-bz5"> - <autoresizingMask key="autoresizingMask"/> - </tableViewCellContentView> - </tableViewCell> - </prototypes> - <connections> - <outlet property="dataSource" destination="2Mz-oY-P1s" id="Dyk-6V-CQ7"/> - <outlet property="delegate" destination="2Mz-oY-P1s" id="EVY-Ms-veo"/> - </connections> - </tableView> - </tableViewController> - <placeholder placeholderIdentifier="IBFirstResponder" id="kX3-kT-KaE" userLabel="First Responder" sceneMemberID="firstResponder"/> - </objects> - <point key="canvasLocation" x="1971" y="143"/> + <point key="canvasLocation" x="1967" y="-722"/> </scene> </scenes> + <inferredMetricsTieBreakers> + <segue reference="u9Y-bO-Pfj"/> + </inferredMetricsTieBreakers> </document> diff --git a/ios-ng/shlist/ListDetailTableViewController.m b/ios-ng/shlist/ListDetailTableViewController.m @@ -98,7 +98,10 @@ - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListDetailPrototypeCell" forIndexPath:indexPath]; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListDetailPrototypeCell" + forIndexPath:indexPath]; + + NSUInteger section = [indexPath section]; // NSLog(@"ListDetailTableViewController::cellForRowAtIndexPath()"); // Tags: @@ -114,12 +117,12 @@ if (item.modifier == 1) { UIImageView *image_view; image_view = (UIImageView *)[cell viewWithTag:1]; - image_view.image = [UIImage imageNamed: @"dollar103-4.png"]; + image_view.image = [UIImage imageNamed: @"dollar103-2.png"]; } else if (item.modifier == 2) { UIImageView *image_view; image_view = (UIImageView *)[cell viewWithTag:1]; - image_view.image = [UIImage imageNamed: @"information15-2.png"]; + image_view.image = [UIImage imageNamed: @"information15-3.png"]; } label = (UILabel *)[cell viewWithTag:2]; @@ -133,10 +136,17 @@ } label = (UILabel *)[cell viewWithTag:4]; - // XXX: this should go to N/A when item doesn't have an owner - label.text = item.owner; - - // label = (UILabel *)[cell viewWithTag:5]; + if (section == 0) + // XXX: this should go to N/A when item doesn't have an owner + label.text = item.owner; + else + label.hidden = true; + + label = (UILabel *)[cell viewWithTag:5]; + if (section == 0) + ; + else + label.hidden = true; return cell; } diff --git a/ios-ng/shlist/SharedListsTableViewController.m b/ios-ng/shlist/SharedListsTableViewController.m @@ -4,6 +4,8 @@ #import "ShlistServer.h" #import "ListDetailTableViewController.h" +#import <AddressBook/AddressBook.h> + @interface SharedListsTableViewController () @property (strong, nonatomic) ShlistServer *server; @@ -110,6 +112,7 @@ self.indirect_lists = [[NSMutableArray alloc] init]; [self load_initial_data]; + } - (void) didReceiveMemoryWarning diff --git a/ios-ng/shlist/ShlistServer.m b/ios-ng/shlist/ShlistServer.m @@ -1,9 +1,11 @@ #import "ShlistServer.h" #import "SharedList.h" +#import "AddressBook.h" @interface ShlistServer () @property (strong, retain) NSMutableData *data; +@property (strong, retain) AddressBook *address_book; @end @@ -31,6 +33,8 @@ [inputShlistStream open]; [outputShlistStream open]; */ + + _address_book = [[AddressBook alloc] init]; } return self; @@ -122,67 +126,7 @@ } if (msg_type == 3) { - NSLog(@"info: read: processing bulk list update message"); - - // split over double \0 - NSArray *list_types = [output componentsSeparatedByString:@"\0\0"]; - if ([list_types count] != 2) { - NSLog(@"warn: more than one \\0\\0 found in response"); - break; - } - - // split over \0 - NSString *direct_list_str = [list_types objectAtIndex:0]; - NSString *indirect_list_str = [list_types objectAtIndex:1]; - - if ([direct_list_str length] != 0) { - NSArray *direct_lists = [direct_list_str componentsSeparatedByString:@"\0"]; - [shlist_tvc.shared_lists removeAllObjects]; - - for (id str in direct_lists) { - // NSLog(@"info: got raw direct list %@", str); - - NSArray *broken_down_list = [str componentsSeparatedByString:@":"]; - - SharedList *shared_list = [[SharedList alloc] init]; - shared_list.list_name = [broken_down_list objectAtIndex:0]; - shared_list.list_id = [broken_down_list objectAtIndex:1]; - shared_list.list_members = [broken_down_list objectAtIndex:2]; - - NSLog(@"info: network: got direct list '%@'", shared_list.list_name); - [shlist_tvc.shared_lists addObject:shared_list]; - - // [direct_shared_lists addObject:shared_list]; - } - - } - if ([indirect_list_str length] != 0) { - NSArray *indirect_lists = [indirect_list_str componentsSeparatedByString:@"\0"]; - [shlist_tvc.indirect_lists removeAllObjects]; - - for (id str in indirect_lists) { - NSArray *broken_down_list = [str componentsSeparatedByString:@":"]; - - SharedList *shared_list = [[SharedList alloc] init]; - shared_list.list_name = [broken_down_list objectAtIndex:0]; - shared_list.list_id = [broken_down_list objectAtIndex:1]; - shared_list.list_members = [broken_down_list objectAtIndex:2]; - - NSLog(@"info: network: got indirect list '%@'", shared_list.list_name); - [shlist_tvc.indirect_lists addObject:shared_list]; - } - } - [shlist_tvc.tableView reloadData]; - - /* - dispatch_async(dispatch_get_main_queue(), ^{ - shlist_tvc.shared_lists = direct_shared_lists; - [shlist_tvc.tableView reloadData]; - }); - */ - // [shlist_tvc update_shared_lists:direct_shared_lists :indirect_shared_lists]; - - // NSLog(@"info: %i direct lists, %i indirect lists"); + [self handle_bulk_list_update:output]; } if (msg_type == 4) { @@ -242,6 +186,100 @@ } } +- (void) handle_bulk_list_update:(NSString *)raw_data +{ + NSLog(@"info: handling bulk list update message"); + + // split over double \0 + NSArray *list_types = [raw_data componentsSeparatedByString:@"\0\0"]; + if ([list_types count] != 2) { + NSLog(@"warn: wrong number if \\0\\0 found: %i", [list_types count]); + return; + } + + NSString *my_lists = [list_types objectAtIndex:0]; + NSString *my_friends_lists = [list_types objectAtIndex:1]; + + [shlist_tvc.shared_lists removeAllObjects]; + [shlist_tvc.indirect_lists removeAllObjects]; + + if ([my_lists length] != 0) { + NSArray *my_lists_parsed = [self parse_lists:my_lists]; + [shlist_tvc.shared_lists addObjectsFromArray:my_lists_parsed]; + } + if ([my_friends_lists length] != 0) { + NSArray *indirect_lists = [self parse_lists:my_friends_lists]; + [shlist_tvc.indirect_lists addObjectsFromArray:indirect_lists]; + } + + [shlist_tvc.tableView reloadData]; +} + +- (NSArray *) parse_lists:(NSString *)raw_lists +{ + // each raw list is separated by a \0 + NSArray *lists = [raw_lists componentsSeparatedByString:@"\0"]; + NSMutableArray *output = [[NSMutableArray alloc] init]; + + for (id str in lists) { + NSArray *list_fields = [str componentsSeparatedByString:@":"]; + int field_count = [list_fields count]; + + if (field_count < 3) { + NSLog(@"warn: less than 3 fields found: %i", field_count); + + // can't do anything with this list + continue; + } + NSLog(@"info: parse_list: '%@' has %i fields", + [list_fields objectAtIndex:0], field_count); + + + NSMutableArray *friends = [[NSMutableArray alloc] init]; + int others = 0; + + // anything past the second field are list members + NSArray *phone_numbers = [list_fields subarrayWithRange:NSMakeRange(2, field_count - 2)]; + for (id phone_number in phone_numbers) { + + /* try to find the list member in our address book */ + NSString *name = _address_book.name_map[phone_number]; + + if (name) + [friends addObject:name]; + else + /* didn't find it, you don't know this person */ + others++; + } + + NSMutableString *members_str = + [[friends componentsJoinedByString:@", "] mutableCopy]; + + if (others) { + char *plural; + if (others == 1) + plural = "other"; + else + plural = "others"; + + NSString *buf = [NSString stringWithFormat:@" + %i %s", + others, plural]; + [members_str appendString:buf]; + } + + /* we've got everything we need */ + SharedList *shared_list = [[SharedList alloc] init]; + + shared_list.list_name = [list_fields objectAtIndex:0]; + shared_list.list_id = [list_fields objectAtIndex:1]; + shared_list.list_members = members_str; + + [output addObject:shared_list]; + } + + return output; +} + - (void) dealloc { [inputShlistStream close];