commit 4fa7f7baac7418a7850c3dd49186a15908103528
parent aa3d22bff3e0a42a3106288b8bba6f7375edf6e2
Author: Kyle Milz <kyle@Kyles-MacBook-Pro.local>
Date: Sun, 13 Sep 2015 19:20:33 -0600
ios: make address book class a singleton
Diffstat:
10 files changed, 475 insertions(+), 132 deletions(-)
diff --git a/ios-ng/ContactsTableViewController.h b/ios-ng/ContactsTableViewController.h
@@ -0,0 +1,5 @@
+#import <UIKit/UIKit.h>
+
+@interface ContactsTableViewController : UITableViewController
+
+@end
+\ No newline at end of file
diff --git a/ios-ng/ContactsTableViewController.m b/ios-ng/ContactsTableViewController.m
@@ -0,0 +1,161 @@
+#import "ContactsTableViewController.h"
+#import "AddressBook.h"
+
+@interface ContactsTableViewController ()
+
+@property (strong, retain) AddressBook *address_book;
+@property (strong, retain) NSMutableArray *cells;
+@property (strong, retain) NSArray *section_to_letter;
+
+@end
+
+@implementation ContactsTableViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ // Uncomment the following line to preserve selection between presentations.
+ // self.clearsSelectionOnViewWillAppear = NO;
+
+ // get a copy of the address book singleton
+ _address_book = [AddressBook shared_address_book];
+
+ // we'll always have 26 or less letters in this dictionary
+ NSMutableDictionary *letter_to_contact_map = [NSMutableDictionary dictionaryWithCapacity:26];
+
+ for (Contact *contact in _address_book.contacts) {
+ NSString *letter;
+ if (contact.last_name)
+ letter = [[contact.last_name uppercaseString] substringToIndex:1];
+ else if (contact.first_name)
+ letter = [[contact.first_name uppercaseString] substringToIndex:1];
+ else
+ // not sure if this can happen or not
+ continue;
+
+ if (letter_to_contact_map[letter] != nil)
+ [[letter_to_contact_map objectForKey:letter] addObject:contact];
+ else {
+ NSMutableArray *tmp = [NSMutableArray arrayWithObject:contact];
+ [letter_to_contact_map setObject:tmp forKey:letter];
+ }
+ }
+
+ // get an array of first letters sorted lexicographically
+ _section_to_letter = [[letter_to_contact_map allKeys]
+ sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
+ _cells = [[NSMutableArray alloc] init];
+
+ for (NSString *letter in _section_to_letter)
+ [_cells addObject:[letter_to_contact_map objectForKey:letter]];
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return [_cells count];
+}
+
+- (NSInteger)tableView:(UITableView *)tableView
+ numberOfRowsInSection:(NSInteger)section
+{
+ return [[_cells objectAtIndex:section] count];
+}
+
+
+- (UITableViewCell *)tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ int section = [indexPath section];
+ int row = [indexPath row];
+ Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row];
+
+ UITableViewCell *cell;
+ if (contact.first_name && contact.last_name)
+ cell = [tableView dequeueReusableCellWithIdentifier:@"contact_cell_two_name" forIndexPath:indexPath];
+ else
+ cell = [tableView dequeueReusableCellWithIdentifier:@"contact_cell_one_name" forIndexPath:indexPath];
+
+ if (contact.first_name && contact.last_name) {
+ UILabel *first = (UILabel *)[cell viewWithTag:1];
+ UILabel *second_bold = (UILabel *)[cell viewWithTag:2];
+
+ first.text = contact.first_name;
+ second_bold.text = contact.last_name;
+ }
+ else if (contact.first_name) {
+ // no last name
+ UILabel *first = (UILabel *)[cell viewWithTag:1];
+ first.text = contact.first_name;
+ }
+ else if (contact.last_name) {
+ // no first name
+ UILabel *first = (UILabel *)[cell viewWithTag:1];
+ first.text = contact.last_name;
+ }
+ else {
+ UILabel *first = (UILabel *)[cell viewWithTag:1];
+ // neither first nor last names exist
+ // show first phone number if we have no other info
+ first.text = [contact.phone_numbers objectAtIndex:0];
+ }
+
+ return cell;
+}
+
+// row was selected, toggle the accessory checkmark and call network functions
+- (void)tableView:(UITableView *)tableView
+ didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ int section = [indexPath section];
+ int row = [indexPath row];
+
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+
+ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
+ Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row];
+
+ if ([cell accessoryType] == UITableViewCellAccessoryNone)
+ [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
+ else
+ [cell setAccessoryType:UITableViewCellAccessoryNone];
+
+ NSLog(@"info: selected %@ %@ who has %i phone numbers",
+ contact.first_name, contact.last_name, [contact.phone_numbers count]);
+}
+
+// programatically assign section headers, in this case they're letters
+- (NSString *)tableView:(UITableView *)tableView
+ titleForHeaderInSection:(NSInteger)section
+{
+ return [_section_to_letter objectAtIndex:section];
+}
+
+// needed to make the section header font bigger
+- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view
+ forSection:(NSInteger)section
+{
+ UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
+
+ header.textLabel.font = [UIFont boldSystemFontOfSize:18];
+}
+
+
+// these two delegates below put the "quick index" ribbon on the right side
+- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
+{
+ return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
+}
+
+- (NSInteger)tableView:(UITableView *)tableView
+ sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
+{
+ return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
+}
+
+@end
+\ No newline at end of file
diff --git a/ios-ng/shlist.xcodeproj/project.pbxproj b/ios-ng/shlist.xcodeproj/project.pbxproj
@@ -23,6 +23,7 @@
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 */; };
+ 27D805731BA2649D00867494 /* ContactsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27D805721BA2649D00867494 /* ContactsTableViewController.m */; };
27DCC9DE1B8A98D400207340 /* dollar103-2.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DCC9DD1B8A98D400207340 /* dollar103-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 */; };
@@ -69,6 +70,8 @@
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; };
+ 27D805711BA2649D00867494 /* ContactsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsTableViewController.h; sourceTree = SOURCE_ROOT; };
+ 27D805721BA2649D00867494 /* ContactsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsTableViewController.m; sourceTree = SOURCE_ROOT; };
27DCC9DD1B8A98D400207340 /* dollar103-2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dollar103-2.png"; path = "../../../Downloads/dollar103-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>"; };
@@ -134,6 +137,8 @@
27DCC9EA1B9FF89E00207340 /* AddressBook.m */,
27C70F061B32AF8000DADEB3 /* AppDelegate.h */,
27C70F071B32AF8000DADEB3 /* AppDelegate.m */,
+ 27D805711BA2649D00867494 /* ContactsTableViewController.h */,
+ 27D805721BA2649D00867494 /* ContactsTableViewController.m */,
27B039FD1B43B6830054B6D2 /* ContactsViewController.h */,
27B039FE1B43B6830054B6D2 /* ContactsViewController.m */,
27DCC9DD1B8A98D400207340 /* dollar103-2.png */,
@@ -290,6 +295,7 @@
27AAC22C1B50ABAF00D99171 /* NewItemTableViewController.m in Sources */,
BF7776BC1B38D0DB00526CB0 /* ListItem.m in Sources */,
27C70F0B1B32AF8000DADEB3 /* ShlistServer.m in Sources */,
+ 27D805731BA2649D00867494 /* ContactsTableViewController.m in Sources */,
27C70F2A1B33D1C900DADEB3 /* SharedList.m in Sources */,
27C70F2D1B33F3C300DADEB3 /* NewListViewController.m in Sources */,
27C70F081B32AF8000DADEB3 /* AppDelegate.m in Sources */,
diff --git a/ios-ng/shlist/AddressBook.h b/ios-ng/shlist/AddressBook.h
@@ -2,6 +2,22 @@
@interface AddressBook : NSObject
-@property NSMutableDictionary *name_map;
+@property (strong, retain) NSMutableArray *contacts;
+@property int num_contacts;
+
+// returns singleton instance
++ (id) shared_address_book;
+
+- (void) wait_for_ready;
+
+@property int ready;
@end
+
+@interface Contact : NSObject
+
+@property NSString *first_name;
+@property NSString *last_name;
+@property NSMutableArray *phone_numbers;
+
+@end
+\ No newline at end of file
diff --git a/ios-ng/shlist/AddressBook.m b/ios-ng/shlist/AddressBook.m
@@ -2,14 +2,33 @@
#include <AddressBook/AddressBook.h>
#import <UIKit/UIKit.h>
+@interface AddressBook ()
+
+@end
+
+// empty implementation
+@implementation Contact
+@end
@implementation AddressBook
++ (id)shared_address_book
+{
+ static AddressBook *address_book = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ address_book = [[self alloc] init];
+ address_book.ready = 0;
+ });
+ return address_book;
+}
+
- (id)init
{
self = [super init];
if (self)
{
+ _contacts = [[NSMutableArray alloc] init];
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status == kABAuthorizationStatusDenied || status == kABAuthorizationStatusRestricted) {
@@ -30,6 +49,8 @@
return self;
}
+ // ABAddressBookRegisterExternalChangeCallback(<#ABAddressBookRef addressBook#>, <#ABExternalChangeCallback callback#>, <#void *context#>)
+
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (error) {
NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error));
@@ -60,46 +81,59 @@
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];
+ Contact *contact = [[Contact alloc] init];
- NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
- // NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
- // NSLog(@"Name:%@ %@", firstName, lastName);
+ // don't enforce these existing on purpose
+ contact.first_name = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
+ contact.last_name = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
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);
+ contact.phone_numbers = [[NSMutableArray alloc] init];
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
+ if (phoneNumber == nil)
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);
+ [contact.phone_numbers addObject:phoneNumber];
}
-
CFRelease(phoneNumbers);
- // NSLog(@"=============================================");
+ [_contacts addObject:contact];
+ }
+
+ _num_contacts = [_contacts count];
+ _ready = 1;
+
+ NSLog(@"info: address book: %i contacts found", _num_contacts);
+}
+
+- (void) wait_for_ready
+{
+ int cumulative_ms = 0;
+ int sleep_for_ms = 10;
+ // wait for the database to become ready, no upper bound
+ while (!_ready) {
+ usleep(sleep_for_ms * 1000);
+ cumulative_ms += sleep_for_ms;
+
+ // if we've spun for over a second reduce polling speed
+ if (cumulative_ms > 1 * 1000) {
+ NSLog(@"warn: address book: not ready for more than %i s",
+ cumulative_ms / 1000);
+ sleep_for_ms = 1 * 1000;
+ }
}
+
+ NSLog(@"info: address book: ready after %i ms", cumulative_ms);
}
@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
@@ -30,7 +30,7 @@
<label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Name" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="btC-Lf-VTy">
<rect key="frame" x="32" y="11" width="46" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" tag="5" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="n1B-AB-bme">
@@ -39,7 +39,7 @@
<label opaque="NO" userInteractionEnabled="NO" tag="4" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Owner" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0TP-dF-f2P">
<rect key="frame" x="451" y="11" width="51" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" tag="3" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Quantity" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="upb-uA-yH2">
@@ -84,7 +84,7 @@
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="H64-xB-1er" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="1172" y="-270"/>
+ <point key="canvasLocation" x="1984" y="-270"/>
</scene>
<!--Add Item-->
<scene sceneID="OeV-vW-TVD">
@@ -93,7 +93,7 @@
<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"/>
+ <color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="calibratedRGB"/>
<sections>
<tableViewSection headerTitle="Item Details" id="2DB-BM-NLj">
<cells>
@@ -105,7 +105,7 @@
<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"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="<item name>" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RxZ-xc-Qog">
@@ -129,7 +129,7 @@
<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"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<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">
@@ -157,7 +157,7 @@
<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"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@@ -179,7 +179,7 @@
<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"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="<persons name>" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Y92-Cj-Q4R">
@@ -203,7 +203,7 @@
<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"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="<cost>" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QhL-xd-rVc">
@@ -243,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="1967" y="61"/>
+ <point key="canvasLocation" x="2779" y="117"/>
</scene>
<!--Shlist-->
<scene sceneID="hc1-Lv-WtP">
@@ -254,27 +254,27 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<prototypes>
- <tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SharedListPrototypeCell" textLabel="zqW-ht-Knz" detailTextLabel="C9r-D2-l6m" style="IBUITableViewCellStyleSubtitle" id="cBl-Ro-lD0">
+ <tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SharedListPrototypeCell" textLabel="3Op-tK-Z2y" detailTextLabel="HIh-Ve-1bs" style="IBUITableViewCellStyleSubtitle" id="cBl-Ro-lD0">
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="cBl-Ro-lD0" id="EBK-6r-ANI">
<autoresizingMask key="autoresizingMask"/>
<subviews>
- <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="zqW-ht-Knz">
+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="3Op-tK-Z2y">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
- <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="C9r-D2-l6m">
+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Detail" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HIh-Ve-1bs">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
- <label opaque="NO" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="3/9" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1XQ-ac-kMc">
- <rect key="frame" x="262" y="11" width="29" height="21"/>
- <fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+ <label opaque="NO" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="shg-tw-Fa9">
+ <rect key="frame" x="260" y="5" width="59" height="34"/>
+ <fontDescription key="fontDescription" type="system" pointSize="22"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@@ -386,25 +386,6 @@
</objects>
<point key="canvasLocation" x="2044" y="811"/>
</scene>
- <!--Contacts-->
- <scene sceneID="QO3-Nz-2Rw">
- <objects>
- <viewController id="U8c-wO-OWj" userLabel="Contacts" customClass="ContactsViewController" sceneMemberID="viewController">
- <layoutGuides>
- <viewControllerLayoutGuide type="top" id="lbu-UM-pRT"/>
- <viewControllerLayoutGuide type="bottom" id="FAF-HB-8uI"/>
- </layoutGuides>
- <view key="view" contentMode="scaleToFill" id="rZG-yU-46M">
- <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"/>
- </view>
- <tabBarItem key="tabBarItem" systemItem="contacts" id="Ify-RM-5Th"/>
- </viewController>
- <placeholder placeholderIdentifier="IBFirstResponder" id="ess-Hw-XyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
- </objects>
- <point key="canvasLocation" x="292" y="-702"/>
- </scene>
<!--Tab Bar Controller-->
<scene sceneID="TmM-gX-MFR">
<objects>
@@ -417,13 +398,79 @@
</tabBar>
<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="H4q-bc-jfz" kind="relationship" relationship="viewControllers" id="9us-ML-Tfz"/>
</connections>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="PWN-St-ASU" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-520" y="-702"/>
</scene>
+ <!--All Contacts-->
+ <scene sceneID="J4l-EM-mPs">
+ <objects>
+ <tableViewController id="eq7-8Y-2gk" customClass="ContactsTableViewController" sceneMemberID="viewController">
+ <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="cQe-3h-KwL">
+ <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" reuseIdentifier="contact_cell_two_name" id="tob-T5-7c2">
+ <autoresizingMask key="autoresizingMask"/>
+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tob-T5-7c2" id="EB4-t3-yo4">
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Zoe-VX-ha7">
+ <rect key="frame" x="16" y="11" width="42" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ <label opaque="NO" userInteractionEnabled="NO" tag="2" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YPU-sZ-aBG">
+ <rect key="frame" x="66" y="11" width="44" height="21"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="centerY" secondItem="Zoe-VX-ha7" secondAttribute="centerY" id="1f5-Qr-raP"/>
+ <constraint firstAttribute="centerY" secondItem="YPU-sZ-aBG" secondAttribute="centerY" id="96i-ka-jL9"/>
+ <constraint firstItem="Zoe-VX-ha7" firstAttribute="leading" secondItem="EB4-t3-yo4" secondAttribute="leadingMargin" constant="8" id="SJ7-N9-uE4"/>
+ <constraint firstItem="YPU-sZ-aBG" firstAttribute="leading" secondItem="Zoe-VX-ha7" secondAttribute="trailing" constant="8" id="nze-5F-xiv"/>
+ </constraints>
+ </tableViewCellContentView>
+ </tableViewCell>
+ <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="contact_cell_one_name" id="MmX-cP-MzC">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
+ <autoresizingMask key="autoresizingMask"/>
+ <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MmX-cP-MzC" id="iHy-1R-Dp6">
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" tag="1" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jWS-GM-KOz">
+ <rect key="frame" x="16" y="11" width="44" height="21"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+ <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="centerY" secondItem="jWS-GM-KOz" secondAttribute="centerY" id="9Wg-kH-pQN"/>
+ <constraint firstItem="jWS-GM-KOz" firstAttribute="leading" secondItem="iHy-1R-Dp6" secondAttribute="leadingMargin" constant="8" id="ePe-7u-V2o"/>
+ </constraints>
+ </tableViewCellContentView>
+ </tableViewCell>
+ </prototypes>
+ <connections>
+ <outlet property="dataSource" destination="eq7-8Y-2gk" id="vru-iM-UFI"/>
+ <outlet property="delegate" destination="eq7-8Y-2gk" id="2sK-Wj-rpe"/>
+ </connections>
+ </tableView>
+ <navigationItem key="navigationItem" title="All Contacts" id="12T-BK-psp"/>
+ </tableViewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="1ye-ky-exR" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="1072" y="-702"/>
+ </scene>
<!--Shared Lists-->
<scene sceneID="vP4-SE-UGa">
<objects>
@@ -477,7 +524,26 @@
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="AR0-99-D0J" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="1967" y="-722"/>
+ <point key="canvasLocation" x="2779" y="-722"/>
+ </scene>
+ <!--Navigation Controller-->
+ <scene sceneID="9uD-bo-9f6">
+ <objects>
+ <navigationController automaticallyAdjustsScrollViewInsets="NO" id="H4q-bc-jfz" sceneMemberID="viewController">
+ <tabBarItem key="tabBarItem" systemItem="contacts" id="LgJ-3E-asO"/>
+ <toolbarItems/>
+ <navigationBar key="navigationBar" contentMode="scaleToFill" id="wuQ-EG-WNy">
+ <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </navigationBar>
+ <nil name="viewControllers"/>
+ <connections>
+ <segue destination="eq7-8Y-2gk" kind="relationship" relationship="rootViewController" id="D2Z-hc-bxH"/>
+ </connections>
+ </navigationController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="ioj-Fm-IP0" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="260" y="-702"/>
</scene>
</scenes>
<inferredMetricsTieBreakers>
diff --git a/ios-ng/shlist/ListDetailTableViewController.m b/ios-ng/shlist/ListDetailTableViewController.m
@@ -96,7 +96,8 @@
return @"";
}
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+- (UITableViewCell *) tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ListDetailPrototypeCell"
forIndexPath:indexPath];
diff --git a/ios-ng/shlist/SharedList.h b/ios-ng/shlist/SharedList.h
@@ -11,6 +11,9 @@
@property NSString *list_members;
@property NSDate *list_date;
+@property int items_ready;
+@property int items_total;
+
@end
-#endif
+#endif
+\ No newline at end of file
diff --git a/ios-ng/shlist/SharedListsTableViewController.m b/ios-ng/shlist/SharedListsTableViewController.m
@@ -61,7 +61,6 @@
self.indirect_lists = [[NSMutableArray alloc] init];
[self load_initial_data];
-
}
- (void) didReceiveMemoryWarning
@@ -79,12 +78,10 @@
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
- if (section == 0) {
+ if (section == 0)
return [self.shared_lists count];
- }
- else if (section == 1) {
+ else if (section == 1)
return [self.indirect_lists count];
- }
return 0;
}
@@ -95,36 +92,42 @@
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
-- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+- (UITableViewCell *) tableView:(UITableView *)tableView
+ cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
- // NSLog(@"SharedListsTableViewController::cellForRowAtIndexPath()");
+ int row = [indexPath row];
- NSInteger section_number = [indexPath section];
- if (section_number == 0) {
+ if ([indexPath section] == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:@"SharedListPrototypeCell" forIndexPath:indexPath];
- // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SharedListPrototypeCell"];
-
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"SharedListPrototypeCell"];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- }
- SharedList *shared_list = [self.shared_lists objectAtIndex:indexPath.row];
+ SharedList *shared_list = [self.shared_lists objectAtIndex:row];
cell.textLabel.text = shared_list.list_name;
cell.detailTextLabel.text = shared_list.list_members;
+
+ // fill in the completion fraction
+ UILabel *completion_fraction;
+ completion_fraction = (UILabel *)[cell viewWithTag:1];
+
+ // set color based on how complete the list is
+ float frac = (float) shared_list.items_ready / shared_list.items_total;
+ if (frac == 0.0f)
+ completion_fraction.textColor = [UIColor blackColor];
+ else if (frac < 0.5f)
+ completion_fraction.textColor = [UIColor redColor];
+ else if (frac < 0.75f)
+ completion_fraction.textColor = [UIColor orangeColor];
+ else
+ completion_fraction.textColor = [UIColor greenColor];
+
+ completion_fraction.text = [self fraction:shared_list.items_ready
+ denominator:shared_list.items_total];
}
- else if (section_number == 1) {
+ else if ([indexPath section] == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:@"IndirectListPrototypeCell" forIndexPath:indexPath];
- // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SharedListPrototypeCell"];
-
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"IndirectListPrototypeCell"];
- cell.selectionStyle = UITableViewCellSelectionStyleNone;
- }
- SharedList *shared_list = [self.indirect_lists objectAtIndex:indexPath.row];
+ SharedList *shared_list = [self.indirect_lists objectAtIndex:row];
cell.textLabel.text = shared_list.list_name;
cell.detailTextLabel.text = shared_list.list_members;
}
@@ -132,24 +135,51 @@
return cell;
}
+
+// taken from http://stackoverflow.com/questions/30859359/display-fraction-number-in-uilabel
+-(NSString *)fraction:(int)numerator denominator:(int)denominator {
+
+ NSMutableString *result = [NSMutableString string];
+
+ NSString *one = [NSString stringWithFormat:@"%i", numerator];
+ for (int i = 0; i < one.length; i++) {
+ [result appendString:[self superscript:[[one substringWithRange:NSMakeRange(i, 1)] intValue]]];
+ }
+ [result appendString:@"/"];
+
+ NSString *two = [NSString stringWithFormat:@"%i", denominator];
+ for (int i = 0; i < two.length; i++) {
+ [result appendString:[self subscript:[[two substringWithRange:NSMakeRange(i, 1)] intValue]]];
+ }
+ return result;
+}
+
+-(NSString *)superscript:(int)num
+{
+ NSDictionary *superscripts = @{@0: @"\u2070", @1: @"\u00B9", @2: @"\u00B2", @3: @"\u00B3", @4: @"\u2074", @5: @"\u2075", @6: @"\u2076", @7: @"\u2077", @8: @"\u2078", @9: @"\u2079"};
+ return superscripts[@(num)];
+}
+
+-(NSString *)subscript:(int)num
+{
+ NSDictionary *subscripts = @{@0: @"\u2080", @1: @"\u2081", @2: @"\u2082", @3: @"\u2083", @4: @"\u2084", @5: @"\u2085", @6: @"\u2086", @7: @"\u2087", @8: @"\u2088", @9: @"\u2089"};
+ return subscripts[@(num)];
+}
+
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
- if ([self.shared_lists count] == 0) {
+ if ([self.shared_lists count] == 0)
return @"you're not in any lists";
- }
- else if ([self.shared_lists count] == 1) {
+ else if ([self.shared_lists count] == 1)
return @"shared list";
- }
return @"shared lists";
}
else if (section == 1) {
- if ([self.indirect_lists count] == 0) {
+ if ([self.indirect_lists count] == 0)
return @"no other shared lists";
- }
- else if ([self.indirect_lists count] == 1) {
+ else if ([self.indirect_lists count] == 1)
return @"other shared list";
- }
return @"other shared lists";
}
return @"";
@@ -158,24 +188,18 @@
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
- if ([indexPath section] == 0) {
+ if ([indexPath section] == 0)
return UITableViewCellEditingStyleDelete;
- }
+
return UITableViewCellEditingStyleInsert;
}
-// Override to support conditional editing of the table view.
- (BOOL) tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
- // if ([indexPath section] == 0) {
- // editable
- return YES;
- // }
-
- // return NO;
+ // all lists are editable
+ return YES;
}
-// Override to support editing the table view.
- (void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
@@ -184,6 +208,9 @@
// Delete the row from the data source
// [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
+ //NSIndexPath *new_index_path = [NSIndexPath indexPathForRow:0 inSection:1];
+ //[tableView moveRowAtIndexPath:indexPath toIndexPath:new_index_path];
+
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
SharedList *selected_list = [self.shared_lists objectAtIndex:[path row]];
@@ -206,25 +233,11 @@
}
}
-/*
-// Override to support rearranging the table view.
-- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
-}
-*/
-
-/*
-// Override to support conditional rearranging of the table view.
-- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
- // Return NO if you do not want the item to be re-orderable.
- return YES;
-}
-*/
-
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
- // Get the new view controller using [segue destinationViewController].
- // Pass the selected object to the new view controller.
+ // Get the new view controller using [segue destinationViewController].
+ // Pass the selected object to the new view controller.
if ([[segue identifier] isEqualToString:@"show list segue"]) {
@@ -240,8 +253,7 @@
// send update list items message
[_server send_message:6 contents:list.list_id];
}
- // DetailObject *detail = [self detailForIndexPath:path];
-
+ // DetailObject *detail = [self detailForIndexPath:path];ß
// ListDetailTableViewController *list_detail_tvc = [segue destinationViewController];
// list_detail_tvc.navigationItem.title = @"Test Title";
diff --git a/ios-ng/shlist/ShlistServer.m b/ios-ng/shlist/ShlistServer.m
@@ -6,6 +6,8 @@
@property (strong, retain) NSMutableData *data;
@property (strong, retain) AddressBook *address_book;
+@property NSMutableDictionary *phnum_to_name_map;
+
@property (strong, nonatomic) NSString *phone_number;
@property (strong, nonatomic) NSData *device_id;
@@ -37,7 +39,34 @@
[outputShlistStream open];
*/
- _address_book = [[AddressBook alloc] init];
+ // get instance and wait for privacy window to clear
+ _address_book = [AddressBook shared_address_book];
+ [_address_book wait_for_ready];
+
+ // the capacity here assumes one phone number per person
+ _phnum_to_name_map = [NSMutableDictionary
+ dictionaryWithCapacity:_address_book.num_contacts];
+
+ for (Contact *contact in _address_book.contacts) {
+ NSString *disp_name;
+ // show first name and last initial if possible, otherwise
+ // just show the first name or the last name or the phone number
+ if (contact.first_name && contact.last_name)
+ disp_name = [NSString stringWithFormat:@"%@ %@",
+ contact.first_name, [contact.last_name substringToIndex:1]];
+ else if (contact.first_name)
+ disp_name = contact.first_name;
+ else if (contact.last_name)
+ disp_name = contact.last_name;
+ else if ([contact.phone_numbers count])
+ disp_name = [contact.phone_numbers objectAtIndex:0];
+ else
+ disp_name = @"No Name";
+
+ // map the persons known phone number to their massaged name
+ for (NSString *phone_number in contact.phone_numbers)
+ [_phnum_to_name_map setObject:disp_name forKey:phone_number];
+ }
}
return self;
@@ -62,14 +91,14 @@
// message type 0
[msg appendBytes:"\x00\x00" length:2];
- // phone number length is 9
- uint16_t length_network = htons(9);
+ // phone number length is 10
+ uint16_t length_network = htons(10);
[msg appendBytes:&length_network length:2];
// actual phone number
const char *phone_number = "4037082094";
_phone_number = @"4037082094";
- [msg appendBytes:phone_number length:9];
+ [msg appendBytes:phone_number length:10];
[self writeToServer:msg];
NSLog(@"info: sent registration message");
@@ -309,8 +338,7 @@
NSLog(@"info: parse_list: '%@' has %i fields",
[list_fields objectAtIndex:0], field_count);
-
- NSMutableArray *friends = [[NSMutableArray alloc] init];
+ NSMutableArray *members = [[NSMutableArray alloc] init];
int others = 0;
// anything past the second field are list members
@@ -318,19 +346,20 @@
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];
+ NSString *name = _phnum_to_name_map[phone_number];
+ // NSLog(@"info: %@ -> %@", phone_number, name);
if (name)
- [friends addObject:name];
+ [members addObject:name];
else if ([phone_number compare:_phone_number])
- [friends addObject:@"You"];
+ [members addObject:@"You"];
else
// didn't find it, you don't know this person
others++;
}
NSMutableString *members_str =
- [[friends componentsJoinedByString:@", "] mutableCopy];
+ [[members componentsJoinedByString:@", "] mutableCopy];
if (others) {
char *plural;
@@ -344,13 +373,19 @@
[members_str appendString:buf];
}
- /* we've got everything we need */
+ // 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] dataUsingEncoding:NSUTF8StringEncoding];
shared_list.list_members = members_str;
+ // we don't currently get this information back
+ // XXX: lists your not in will not return this information
+ sranddev();
+ shared_list.items_ready = rand() % 7;
+ shared_list.items_total = 7;
+
[output addObject:shared_list];
}