commit a7a570d95d4f221e3927a8c9e9873714461df6f9
parent 6b27fe83e60bd460f6809aa927917a77d7d6fcae
Author: Kyle Milz <kyle@green.krwm.net>
Date: Thu, 21 Jan 2016 22:20:08 -0700
ios: commit some work in progress stuff
- change message handling over to JSON
- most of the way there, still some left to do
- send friend add/delete messages when contacts selected/deselected :)
- there isn't anything definitively done here, I just don't want to lose this
progress
Diffstat:
13 files changed, 448 insertions(+), 386 deletions(-)
diff --git a/ios/ContactsTableViewController.m b/ios/ContactsTableViewController.m
@@ -1,7 +1,10 @@
#import "ContactsTableViewController.h"
#import "AddressBook.h"
+#import "Network.h"
-@interface ContactsTableViewController ()
+@interface ContactsTableViewController () {
+ Network *network_connection;
+}
@property (strong, retain) AddressBook *address_book;
@property (strong, retain) NSMutableArray *cells;
@@ -49,6 +52,8 @@
for (NSString *letter in _section_to_letter)
[_cells addObject:[letter_to_contact_map objectForKey:letter]];
+
+ network_connection = [Network shared_network_connection];
}
- (void)didReceiveMemoryWarning
@@ -120,13 +125,25 @@
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row];
- if ([cell accessoryType] == UITableViewCellAccessoryNone)
+ NSMutableDictionary *request = [[NSMutableDictionary alloc] init];
+ if ([cell accessoryType] == UITableViewCellAccessoryNone) {
+ // Toggling the contact on, add friend
+
+ [request setObject:[contact.phone_numbers objectAtIndex:0] forKey:@"friend_phnum"];
+ [network_connection send_message:friend_add contents:request];
+
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
- else
+ }
+ else {
+ // Toggling contact off, delete friend
+ [request setObject:[contact.phone_numbers objectAtIndex:0] forKey:@"friend_phnum"];
+ [network_connection send_message:friend_delete contents:request];
+
[cell setAccessoryType:UITableViewCellAccessoryNone];
+ }
NSLog(@"info: selected %@ %@ who has %i phone numbers",
- contact.first_name, contact.last_name, [contact.phone_numbers count]);
+ contact.first_name, contact.last_name, [contact.phone_numbers count]);
}
// programatically assign section headers, in this case they're letters
diff --git a/ios/EditItemTableViewController.m b/ios/EditItemTableViewController.m
@@ -119,7 +119,7 @@
[string_array addObject:[NSString stringWithFormat:@"%i", _item.completed]];
NSMutableData *buffer = [[NSMutableData alloc] init];
- [buffer appendData:_list.id];
+ //[buffer appendData:_list.num];
[buffer appendData:[[string_array componentsJoinedByString:@":"] dataUsingEncoding:NSUTF8StringEncoding]];
// the list item that was just edited will be updated when a response comes
diff --git a/ios/shlist.xcodeproj/project.pbxproj b/ios/shlist.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 273EC9C01BB25B6300CBFCDC /* SettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 273EC9BF1BB25B6300CBFCDC /* SettingsTableViewController.m */; };
27AAC22C1B50ABAF00D99171 /* EditItemTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 27AAC22B1B50ABAF00D99171 /* EditItemTableViewController.m */; };
27B03A021B43B8660054B6D2 /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27B03A001B43B8660054B6D2 /* AddressBook.framework */; };
27C70F051B32AF8000DADEB3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C70F041B32AF8000DADEB3 /* main.m */; };
@@ -38,9 +39,12 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
+ 273EC9BE1BB25B6300CBFCDC /* SettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTableViewController.h; sourceTree = "<group>"; };
+ 273EC9BF1BB25B6300CBFCDC /* SettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTableViewController.m; sourceTree = "<group>"; };
27AAC22A1B50ABAF00D99171 /* EditItemTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditItemTableViewController.h; path = ../EditItemTableViewController.h; sourceTree = "<group>"; };
27AAC22B1B50ABAF00D99171 /* EditItemTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditItemTableViewController.m; path = ../EditItemTableViewController.m; sourceTree = "<group>"; };
27B03A001B43B8660054B6D2 /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
+ 27B195B81C45FEE200D7B2E9 /* MsgTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MsgTypes.h; path = shlist/MsgTypes.h; sourceTree = "<group>"; };
27C70EFF1B32AF8000DADEB3 /* shlist.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = shlist.app; sourceTree = BUILT_PRODUCTS_DIR; };
27C70F031B32AF8000DADEB3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
27C70F041B32AF8000DADEB3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; };
@@ -94,6 +98,7 @@
27C70EF61B32AF7F00DADEB3 = {
isa = PBXGroup;
children = (
+ 27B195B81C45FEE200D7B2E9 /* MsgTypes.h */,
27B03A001B43B8660054B6D2 /* AddressBook.framework */,
27C70F011B32AF8000DADEB3 /* shlist */,
27C70F1B1B32AF8000DADEB3 /* shlistTests */,
@@ -138,6 +143,8 @@
27C70F0A1B32AF8000DADEB3 /* Network.m */,
27C70F2B1B33F3C300DADEB3 /* NewListTableViewController.h */,
27C70F2C1B33F3C300DADEB3 /* NewListTableViewController.m */,
+ 273EC9BE1BB25B6300CBFCDC /* SettingsTableViewController.h */,
+ 273EC9BF1BB25B6300CBFCDC /* SettingsTableViewController.m */,
27C70F021B32AF8000DADEB3 /* Supporting Files */,
);
path = shlist;
@@ -272,6 +279,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 273EC9C01BB25B6300CBFCDC /* SettingsTableViewController.m in Sources */,
BF7776B91B38928D00526CB0 /* ListTableViewController.m in Sources */,
27AAC22C1B50ABAF00D99171 /* EditItemTableViewController.m in Sources */,
27C70F0B1B32AF8000DADEB3 /* Network.m in Sources */,
diff --git a/ios/shlist/Base.lproj/Main.storyboard b/ios/shlist/Base.lproj/Main.storyboard
@@ -602,7 +602,7 @@
<!--Settings-->
<scene sceneID="VVW-AV-daH">
<objects>
- <tableViewController id="fV5-WH-d49" userLabel="Settings" sceneMemberID="viewController">
+ <tableViewController id="fV5-WH-d49" userLabel="Settings" customClass="SettingsTableViewController" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="10" sectionFooterHeight="10" id="0rU-JR-ipU">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -617,14 +617,14 @@
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Phone Number" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="ZPp-x1-VLQ">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <fontDescription key="fontDescription" type="system" pointSize="16"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8ae-6U-Vfz">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <fontDescription key="fontDescription" type="system" pointSize="16"/>
- <color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@@ -633,21 +633,52 @@
<segue destination="eOn-mZ-1W0" kind="showDetail" id="NXM-5v-RjK"/>
</connections>
</tableViewCell>
- <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="0kV-we-bvq" detailTextLabel="hcO-PG-uAA" style="IBUITableViewCellStyleValue1" id="pLe-rJ-ITY">
+ </cells>
+ </tableViewSection>
+ <tableViewSection headerTitle="Diagnostics" id="hrL-3J-GqW">
+ <cells>
+ <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="RtJ-D1-bJk">
+ <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="RtJ-D1-bJk" id="NuS-la-rMS">
+ <autoresizingMask key="autoresizingMask"/>
+ <subviews>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Network" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oz4-Px-uoa">
+ <rect key="frame" x="16" y="11" width="65" 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="Good" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="15d-vN-62f">
+ <rect key="frame" x="541" y="11" width="43" 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="15d-vN-62f" secondAttribute="centerY" id="30n-T2-CIn"/>
+ <constraint firstAttribute="centerY" secondItem="Oz4-Px-uoa" secondAttribute="centerY" id="AYc-kZ-b1z"/>
+ <constraint firstItem="15d-vN-62f" firstAttribute="trailing" secondItem="NuS-la-rMS" secondAttribute="trailingMargin" constant="-8" id="PZV-Nm-lOT"/>
+ <constraint firstItem="Oz4-Px-uoa" firstAttribute="leading" secondItem="NuS-la-rMS" secondAttribute="leadingMargin" constant="8" id="oIz-Vf-gq5"/>
+ </constraints>
+ </tableViewCellContentView>
+ </tableViewCell>
+ <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" textLabel="0kV-we-bvq" detailTextLabel="hcO-PG-uAA" style="IBUITableViewCellStyleValue1" id="pLe-rJ-ITY">
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pLe-rJ-ITY" id="RsW-FA-jWb">
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Device Id" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="0kV-we-bvq">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <fontDescription key="fontDescription" type="system" pointSize="16"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
- <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Detail" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hcO-PG-uAA">
+ <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="0x0" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hcO-PG-uAA">
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
- <fontDescription key="fontDescription" type="system" pointSize="16"/>
- <color key="textColor" red="0.55686274509803924" green="0.55686274509803924" blue="0.57647058823529407" alpha="1" colorSpace="calibratedRGB"/>
+ <fontDescription key="fontDescription" name="Menlo-Regular" family="Menlo" pointSize="17"/>
+ <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@@ -662,6 +693,11 @@
</connections>
</tableView>
<navigationItem key="navigationItem" title="Settings" id="zoA-Im-wFY"/>
+ <connections>
+ <outlet property="device_id_label" destination="hcO-PG-uAA" id="onj-im-8FH"/>
+ <outlet property="network_label" destination="15d-vN-62f" id="eVb-v4-Ade"/>
+ <outlet property="phone_number_label" destination="8ae-6U-Vfz" id="crf-Wn-WIN"/>
+ </connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="BHt-9T-HOU" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
diff --git a/ios/shlist/DataStructures.h b/ios/shlist/DataStructures.h
@@ -8,17 +8,16 @@
// UILabel *names;
@property NSString *name;
-@property NSData *id;
+@property NSNumber *num;
@property NSArray *members_phone_nums;
@property bool deadline;
@property NSDate *date;
-@property int items_ready;
-@property int items_total;
+@property NSNumber *items_ready;
+@property NSNumber *items_total;
@property UITableViewCell *cell;
@end
-
// This object is an individual item in a list
@interface ListItem : NSObject
diff --git a/ios/shlist/MainTableViewController.h b/ios/shlist/MainTableViewController.h
@@ -4,11 +4,9 @@
@interface MainTableViewController : UITableViewController
-@property NSMutableArray *shared_lists;
-@property NSMutableArray *indirect_lists;
-
- (void) update_address_book;
+- (void) lists_get_finished:(NSArray *)lists;
- (void) finished_new_list_request:(SharedList *) shlist;
- (void) finished_join_list_request:(SharedList *) shlist;
- (void) finished_leave_list_request:(SharedList *) shlist;
diff --git a/ios/shlist/MainTableViewController.m b/ios/shlist/MainTableViewController.m
@@ -3,6 +3,7 @@
#import "NewListTableViewController.h"
#import "Network.h"
#import "ListTableViewController.h"
+#import "MsgTypes.h"
#import <AddressBook/AddressBook.h>
#include "libkern/OSAtomic.h"
@@ -13,6 +14,9 @@
NSString *phone_num_file;
}
+// main data structure, [0] holds lists you're in, [1] is other lists
+@property NSMutableArray *lists;
+
@property NSMutableDictionary *phnum_to_name_map;
@property (strong, retain) AddressBook *address_book;
@@ -31,9 +35,9 @@
network_connection = [Network shared_network_connection];
network_connection->shlist_tvc = self;
- // main lists
- self.shared_lists = [[NSMutableArray alloc] init];
- self.indirect_lists = [[NSMutableArray alloc] init];
+ _lists = [[NSMutableArray alloc] init];
+ [_lists addObject:[[NSMutableArray alloc] init]];
+ [_lists addObject:[[NSMutableArray alloc] init]];
// store the path to the phone number file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
@@ -43,9 +47,10 @@
phone_number = nil;
if ([self load_phone_number]) {
// phone number loaded, try loading device id
- if ([network_connection load_device_id:[phone_number dataUsingEncoding:NSASCIIStringEncoding]]) {
+ if ([network_connection load_device_id:phone_number]) {
// bulk update, doesn't take a payload
- [network_connection send_message:3 contents:nil];
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
+ [network_connection send_message:lists_get contents:dict];
}
// else, device id request sent
}
@@ -68,7 +73,7 @@
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Important"
- message:@"In order for us to calculate your mutual contacts, your phone number is needed."
+ message:@"Your phone number is needed for us to calculate your mutual contacts. Severe amounts of functionality disabled."
delegate:self cancelButtonTitle:@"Nope" otherButtonTitles:@"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
@@ -99,7 +104,7 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
phone_number = entered_phone_num;
- if ([network_connection load_device_id:[phone_number dataUsingEncoding:NSASCIIStringEncoding]]) {
+ if ([network_connection load_device_id:phone_number]) {
NSLog(@"info: network: connection ready");
// bulk update, doesn't take a payload
[network_connection send_message:3 contents:nil];
@@ -148,11 +153,11 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
- if (section == 0)
- return [self.shared_lists count];
- else if (section == 1)
- return [self.indirect_lists count];
- return 0;
+ if (section > 1)
+ // should never happen
+ return 0;
+
+ return [[_lists objectAtIndex:section] count];
}
// new list dialogue has been saved
@@ -160,12 +165,37 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
{
}
+- (void) lists_get_finished:(NSArray *)json_lists;
+{
+ NSMutableArray *lists = [_lists objectAtIndex:0];
+ [lists removeAllObjects];
+
+ for (NSDictionary *list in json_lists) {
+
+ SharedList *tmp = [[SharedList alloc] init];
+ tmp.num = [list objectForKey:@"num"];
+ tmp.name = [list objectForKey:@"name"];
+ // tmp.date = [list objectForKey:@"date"];
+ tmp.items_ready = [list objectForKey:@"items_complete"];
+ tmp.items_total = [list objectForKey:@"items_total"];
+ NSArray *members = [list objectForKey:@"members"];
+ tmp.members_phone_nums = members;
+ [lists addObject:tmp];
+
+ NSLog(@"adding list '%@'", [list objectForKey:@"name"]);
+ }
+
+ [self.tableView reloadData];
+}
+
- (void) finished_new_list_request:(SharedList *) shlist
{
- [self.shared_lists addObject:shlist];
+ [[_lists objectAtIndex:0] addObject:shlist];
+ // [self.shared_lists addObject:shlist];
// response looks good, insert the new list
- NSIndexPath *index_path = [NSIndexPath indexPathForRow:[self.shared_lists count] - 1 inSection:0];
+ int section_0_rows = [[_lists objectAtIndex:0] count];
+ NSIndexPath *index_path = [NSIndexPath indexPathForRow:section_0_rows - 1 inSection:0];
[self.tableView insertRowsAtIndexPaths:@[index_path] withRowAnimation:UITableViewRowAnimationFade];
}
@@ -180,18 +210,19 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
return;
// we're in section 1 now, a tap down here means we're doing a join list request
- SharedList *list = [self.indirect_lists objectAtIndex:[indexPath row]];
+ SharedList *list = [[_lists objectAtIndex:1] objectAtIndex:[indexPath row]];
NSLog(@"info: joining list '%@'", list.name);
// the response for this does all of the heavy row moving work
- [network_connection send_message:4 contents:list.id];
+ int num = list.num;
+ [network_connection send_message:list_join contents:[NSData dataWithBytes:&num length:sizeof(num)]];
}
- (void) finished_join_list_request:(SharedList *) shlist
{
SharedList *needle = nil;
- for (SharedList *temp in _indirect_lists) {
- if ([temp.id isEqualToData:shlist.id]) {
+ for (SharedList *temp in [_lists objectAtIndex:1]) {
+ if (temp.num == shlist.num) {
needle = temp;
break;
}
@@ -202,15 +233,19 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
return;
// this has to be done before row moving
- [_shared_lists addObject:needle];
- [_indirect_lists removeObject:needle];
+ [[_lists objectAtIndex:0] addObject:needle];
+ [[_lists objectAtIndex:1] removeObject:needle];
+
+ // [_shared_lists addObject:needle];
+ // [_indirect_lists removeObject:needle];
// get the original cells index path from the matched cell
NSIndexPath *orig_index_path = [self.tableView indexPathForCell:needle.cell];
// compute new position and start moving row as soon as possible
// XXX: sorting
- NSIndexPath *new_index_path = [NSIndexPath indexPathForRow:[_shared_lists count] - 1 inSection:0];
+ int section_0_rows = [[_lists objectAtIndex:0] count];
+ NSIndexPath *new_index_path = [NSIndexPath indexPathForRow:section_0_rows - 1 inSection:0];
[self.tableView moveRowAtIndexPath:orig_index_path toIndexPath:new_index_path];
@@ -224,8 +259,8 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
- (void) finished_leave_list_request:(SharedList *) shlist
{
SharedList *list = nil;
- for (SharedList *temp in _shared_lists) {
- if ([temp.id isEqualToData:shlist.id]) {
+ for (SharedList *temp in [_lists objectAtIndex:0]) {
+ if (temp.num == shlist.num) {
list = temp;
break;
}
@@ -235,8 +270,8 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
return;
// insert the new object at the beginning to match gui moving below
- [_indirect_lists insertObject:list atIndex:0];
- [_shared_lists removeObject:list];
+ [[_lists objectAtIndex:1] insertObject:list atIndex:0];
+ [[_lists objectAtIndex:0] removeObject:list];
// perform row move, the destination is the top of "other lists"
NSIndexPath *old_path = [self.tableView indexPathForCell:list.cell];
@@ -259,38 +294,33 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:@"SharedListPrototypeCell" forIndexPath:indexPath];
+ int section = [indexPath section];
int row = [indexPath row];
- SharedList *shared_list;
+ SharedList *shared_list = [[_lists objectAtIndex:section] objectAtIndex:row];
UILabel *deadline_label = (UILabel *)[cell viewWithTag:3];
UILabel *fraction_label = (UILabel *)[cell viewWithTag:4];
if ([indexPath section] == 0) {
// "lists you're in" section
- shared_list = [self.shared_lists objectAtIndex:row];
// XXX: needs to be stored on/sent from the server
deadline_label.text = @"in 3 days";
- // set color based on how complete the list is
- /*
- float frac = (float) shared_list.items_ready / shared_list.items_total;
- if (frac == 0.0f)
- fraction_label.textColor = [UIColor blackColor];
- else if (frac < 0.5f)
- fraction_label.textColor = [UIColor redColor];
- else if (frac < 0.75f)
- fraction_label.textColor = [UIColor orangeColor];
- else
+ // float frac = shared_list.items_ready / shared_list.items_total;
+ float frac = 0.0f;
+ if (frac > 0.80f)
fraction_label.textColor = [UIColor greenColor];
- */
+ fraction_label.hidden = NO;
fraction_label.text = [self fraction:shared_list.items_ready
denominator:shared_list.items_total];
+
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+
}
else if ([indexPath section] == 1) {
// "other lists" section
- shared_list = [self.indirect_lists objectAtIndex:row];
// no deadline
deadline_label.text = @"";
@@ -368,10 +398,15 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section
{
+ if (section > 1)
+ // should not happen
+ return @"";
+
+ int total = [[_lists objectAtIndex:section] count];
if (section == 0)
- return [NSString stringWithFormat:@"Lists you're in (%i)", [_shared_lists count]];
+ return [NSString stringWithFormat:@"Lists you're in (%i)", total];
else if (section == 1)
- return [NSString stringWithFormat:@"Other lists (%i)", [_indirect_lists count]];
+ return [NSString stringWithFormat:@"Other lists (%i)", total];
return @"";
}
@@ -399,11 +434,13 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// we don't need to check for !section 0 because of canEditRowAtIndexPath
- SharedList *list = [self.shared_lists objectAtIndex:[indexPath row]];
- NSLog(@"info: leaving '%@' id '%@'", list.name, list.id);
+ SharedList *list = [[_lists objectAtIndex:0] objectAtIndex:[indexPath row]];
+ NSLog(@"info: leaving '%@' list num '%@'", list.name, list.num);
// send leave list message, response will do all heavy lifting
- [network_connection send_message:5 contents:list.id];
+ NSMutableDictionary *request = [[NSMutableDictionary alloc] init];
+ [request setObject:list.num forKey:@"num"];
+ [network_connection send_message:list_leave contents:request];
}
// customize deletion label text
@@ -420,14 +457,14 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
// a shared list was selected, transfer into detailed view
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
- SharedList *list = [self.shared_lists objectAtIndex:[path row]];
+ SharedList *list = [[_lists objectAtIndex:0] objectAtIndex:[path row]];
// make sure incoming view controller knows about itself
[segue.destinationViewController setMetadata:list];
// send update list items message
network_connection->shlist_ldvc = segue.destinationViewController;
- [network_connection send_message:6 contents:list.id];
+ //[network_connection send_message:6 contents:list.id];
}
// DetailObject *detail = [self detailForIndexPath:path];
@@ -445,21 +482,25 @@ clickedButtonAtIndex:(NSInteger)buttonIndex
}
// taken from http://stackoverflow.com/questions/30859359/display-fraction-number-in-uilabel
--(NSString *)fraction:(int)numerator denominator:(int)denominator
+-(NSString *)fraction:(NSNumber *)numerator denominator:(NSNumber *)denominator
{
NSMutableString *result = [NSMutableString string];
- NSString *one = [NSString stringWithFormat:@"%i", numerator];
+ NSString *one = [numerator stringValue];
for (int i = 0; i < one.length; i++) {
[result appendString:[self superscript:[[one substringWithRange:NSMakeRange(i, 1)] intValue]]];
}
+
[result appendString:@"/"];
+ return result;
+
+ NSString *two = [denominator stringValue];
- 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;
}
diff --git a/ios/shlist/MsgTypes.h b/ios/shlist/MsgTypes.h
@@ -0,0 +1,33 @@
+/* generated Tue 12 Jan 2016 20:40:15 MST */
+#import "Network.h"
+
+/*
+@interface MsgTypes : NSObject {
+ NSPointerArray *array;
+}
+*/
+
+int protocol_version = 0;
+enum msg_types {
+ device_add = 0,
+ friend_add = 1,
+ friend_delete = 2,
+ list_add = 3,
+ list_join = 4,
+ list_leave = 5,
+ lists_get = 6,
+ lists_get_other = 7,
+ list_items_get = 8,
+ list_item_add = 9,
+};
+
+/*
+@end
+@implementation MsgTypes
++ (void)initialize {
+ //array = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
+}
+*/
+
+//NSPointerArray *array = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsOpaqueMemory];
+//NSArray *msg_func = @[[NSValue valueWithPointer:handlerA]];
diff --git a/ios/shlist/Network.h b/ios/shlist/Network.h
@@ -2,6 +2,8 @@
#import "MainTableViewController.h"
#import "ListTableViewController.h"
+#import "SettingsTableViewController.h"
+#import "MsgTypes.h"
@interface Network : NSObject <NSStreamDelegate> {
NSInputStream *inputShlistStream;
@@ -11,14 +13,18 @@
@public
MainTableViewController *shlist_tvc;
ListTableViewController *shlist_ldvc;
+ SettingsTableViewController *settings_tvc;
}
- (void) connect;
- (void) disconnect;
// only networking really cares about the device id
-- (bool) load_device_id:(NSData*)phone_number;
-- (bool) send_message:(uint16_t)msg_type contents:(NSData *)data;
+- (bool) load_device_id:(NSString *)phone_number;
+- (NSData *) get_device_id;
+- (bool) send_message:(uint16_t)msg_type contents:(NSMutableDictionary *)data;
+
+
// returns singleton instance
+ (id) shared_network_connection;
diff --git a/ios/shlist/Network.m b/ios/shlist/Network.m
@@ -1,23 +1,11 @@
#import "Network.h"
#import "DataStructures.h"
+
// #import <NSAlert.h>
@interface Network () {
- NSData *msg_data;
- NSString *msg_string;
- uint8_t msg_buffer[1024];
- unsigned int msg_buf_position;
-
- uint8_t msg_total_bytes_tmp[2];
- unsigned short msg_total_bytes;
- unsigned int msg_total_bytes_pos;
-
- uint8_t msg_type_tmp[2];
- unsigned short msg_type;
- unsigned int msg_type_pos;
-
- NSData *device_id;
+ NSString *device_id;
NSString *device_id_file;
bool connected;
}
@@ -44,13 +32,6 @@
device_id_file = [documentsDirectory stringByAppendingPathComponent:@"shlist_key"];
device_id = nil;
- msg_buf_position = 0;
-
- msg_total_bytes = 0;
- msg_total_bytes_pos = 0;
-
- msg_type = 0;
- msg_type_pos = 0;
connected = 0;
[self connect];
}
@@ -58,6 +39,11 @@
return self;
}
+- (NSString *) get_device_id
+{
+ return device_id;
+}
+
- (void) connect
{
[self info:@"network: connect()"];
@@ -68,7 +54,7 @@
CFStringRef host_name = CFSTR("absentmindedproductions.ca");
- CFStreamCreatePairWithSocketToHost(NULL, host_name, 5437, &readStream, &writeStream);
+ CFStreamCreatePairWithSocketToHost(NULL, host_name, 9999, &readStream, &writeStream);
inputShlistStream = (__bridge NSInputStream *)readStream;
outputShlistStream = (__bridge NSOutputStream *)writeStream;
@@ -78,6 +64,10 @@
[inputShlistStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputShlistStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ // Enable SSL on both streams
+ [inputShlistStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
+ [outputShlistStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
+
[inputShlistStream open];
[outputShlistStream open];
}
@@ -99,13 +89,17 @@
outputShlistStream = nil; // stream is ivar, so reinit it
}
-- (bool) load_device_id:(NSData *)phone_number;
+- (bool) load_device_id:(NSString *)phone_number;
{
if ([[NSFileManager defaultManager] fileExistsAtPath:device_id_file]) {
// TODO: also check the length of the file
// read device id from filesystem into memory
- device_id = [NSData dataWithContentsOfFile:device_id_file];
- [self debug:@"network: device id loaded"];
+ NSError *error = nil;
+ device_id = [NSString stringWithContentsOfFile:device_id_file encoding:NSUTF8StringEncoding error:&error];
+ if (error != nil)
+ NSLog(@"%@", [error userInfo]);
+
+ NSLog(@"network: device id loaded");
return true;
}
@@ -113,16 +107,27 @@
// no device id file found, send a registration message
NSMutableData *msg = [NSMutableData data];
- // message type 0
- uint16_t msg_type_network = htons(0);
- [msg appendBytes:&msg_type_network length:2];
+ NSDictionary *request = [NSDictionary dictionaryWithObjectsAndKeys:
+ phone_number, @"phone_number",
+ @"ios", @"os",
+ nil];
- // phone number length is 10
- uint16_t length_network = htons(10);
- [msg appendBytes:&length_network length:2];
+ NSError *error = nil;
+ NSData *json = [NSJSONSerialization dataWithJSONObject:request options:NSJSONWritingPrettyPrinted error:&error];
+ if (error != nil) {
+ NSLog(@"%@", [error userInfo]);
+ return false;
+ }
- // append phone number
- [msg appendData:phone_number];
+ uint16_t version = htons(0);
+ uint16_t msg_type = htons(device_add);
+ uint16_t length = htons([json length]);
+ [msg appendBytes:&version length:2];
+ [msg appendBytes:&msg_type length:2];
+ [msg appendBytes:&length length:2];
+
+ // Append JSON payload
+ [msg appendData:json];
[outputShlistStream write:[msg bytes] maxLength:[msg length]];
[self info:@"register: sent request"];
@@ -131,35 +136,30 @@
return false;
}
-- (bool) send_message:(uint16_t)send_msg_type contents:(NSData *)payload
+- (bool) send_message:(uint16_t)send_msg_type contents:(NSMutableDictionary *)request
{
if (!connected)
[self connect];
NSMutableData *msg = [NSMutableData data];
+ [request setObject:device_id forKey:@"device_id"];
- uint16_t msg_type_network = htons(send_msg_type);
- [msg appendBytes:&msg_type_network length:2];
-
- int payload_length = 0;
- if (payload)
- // include null separator in this length
- payload_length = [payload length] + 1;
-
- uint16_t msg_len_network = htons([device_id length] + payload_length);
- [msg appendBytes:&msg_len_network length:2];
-
- if (device_id == nil) {
- [self warn:@"network: send_message: called before device_id was ready"];
+ NSError *error = nil;
+ NSData *json = [NSJSONSerialization dataWithJSONObject:request options:NSJSONWritingPrettyPrinted error:&error];
+ if (error != nil) {
+ NSLog(@"%@", [error userInfo]);
return false;
}
- [msg appendData:device_id];
- if (payload) {
- [msg appendBytes:"\0" length:1];
- [msg appendData:payload];
- }
+ uint16_t version = htons(0);
+ uint16_t msg_type_network = htons(send_msg_type);
+ uint16_t length = htons([json length]);
+
+ [msg appendBytes:&version length:2];
+ [msg appendBytes:&msg_type_network length:2];
+ [msg appendBytes:&length length:2];
+ [msg appendData:json];
[self info:@"network: send_message: type %i, %i bytes",
send_msg_type, [msg length]];
@@ -202,12 +202,11 @@
if (stream == inputShlistStream) {
if (![inputShlistStream hasBytesAvailable]) {
- [self warn:@"network: input stream had no bytes available"];
+ [self warn:@"read: input stream had no bytes available"];
break;
}
- // advance the message state machine by at least one byte
- [self process_response_bytes];
+ [self read_ready];
}
break;
}
@@ -245,298 +244,154 @@
}
}
-- (void) process_response_bytes
+- (void) read_ready
{
- uint8_t *buffer = malloc(1024);
- while ([inputShlistStream hasBytesAvailable]) {
-
- unsigned int buffer_pos = 0;
- NSInteger buffer_length;
-
- buffer_length = [inputShlistStream read:buffer maxLength:1024];
- if (buffer_length < 0) {
- [self info:@"network: read returned < 0: %i", buffer_length];
- // XXX: should this be break instead?
- continue;
- }
-
- if (buffer_length == 0) {
- [self info:@"network: buffer length was zero!"];
- // maybe break here instead?
- continue;
- }
- [self debug:@"network: processing %i bytes", buffer_length];
-
- // start receiving a new message
- if (msg_type_pos == 0) {
- msg_type_tmp[0] = buffer[buffer_pos];
- msg_type_pos = 1;
- buffer_pos++;
-
- if (buffer_length == 1)
- // we've exhausted the buffer
- continue;
- }
-
- // if we got here buffer_length > 1
- if (msg_type_pos == 1) {
- msg_type_pos = 2;
- msg_type_tmp[1] = buffer[buffer_pos];
-
- // we read a single byte from the buffer
- buffer_pos++;
-
- // both bytes are available for reading
- msg_type = ntohs(*(uint16_t *)msg_type_tmp);
- if (msg_type > 7) {
- [self warn:@"network: out of range msg type %i", msg_type];
-
- // bad message type, reset message buffer
- msg_type_pos = 0;
- msg_buf_position = 0;
- msg_total_bytes_pos = 0;
- continue;
- }
- [self debug:@"network: parsed message type %i", msg_type];
-
- if (buffer_pos == buffer_length)
- // we've run out of bytes to process
- continue;
- }
-
- // if we got here buffer_pos < buffer_length
- if (msg_total_bytes_pos == 0) {
- msg_total_bytes_pos = 1;
- msg_total_bytes_tmp[0] = buffer[buffer_pos];
- buffer_pos++;
-
- if (buffer_pos == buffer_length)
- // no more bytes to process
- continue;
- }
-
- if (msg_total_bytes_pos == 1) {
- msg_total_bytes_pos = 2;
- msg_total_bytes_tmp[1] = buffer[buffer_pos];
- buffer_pos++;
-
- msg_total_bytes = ntohs(*(uint16_t *)msg_total_bytes_tmp);
- if (msg_total_bytes > 1024 || msg_total_bytes == 0) {
- [self warn:@"network: out of range message length: 0 < %i < 1024",
- msg_total_bytes];
-
- // bad message type, reset message buffer
- msg_type_pos = 0;
- msg_buf_position = 0;
- msg_total_bytes_pos = 0;
- continue;
- }
- [self debug:@"network: message length is %i bytes", msg_total_bytes];
-
- if (buffer_pos == buffer_length)
- // no more bytes to process
- continue;
- }
-
- unsigned int remaining_bytes = buffer_length - buffer_pos;
-
- if (msg_buf_position + remaining_bytes >= msg_total_bytes) {
- [self info:@"network: buffer length has enough space to read complete message"];
-
- unsigned int bytes_for_complete_message = msg_total_bytes - msg_buf_position;
- memcpy(msg_buffer + msg_buf_position, &buffer[buffer_pos], bytes_for_complete_message);
- msg_buf_position += bytes_for_complete_message;
-
- msg_data = [[NSData alloc] initWithBytes:msg_buffer length:msg_total_bytes];
- msg_string = [[NSString alloc] initWithBytes:msg_buffer length:msg_total_bytes encoding:NSASCIIStringEncoding];
-
- [self handle_complete_message];
-
- // reset parsing fields, leave buffer position fields alone though
- msg_buf_position = 0;
- msg_type_pos = 0;
- msg_total_bytes_pos = 0;
-
- // lop off anything else that's remaining in the read buffer
- continue;
- }
+ NSInteger buffer_len;
+ uint16_t header[3];
- // copy any remaining data into msg buffer
- memcpy(msg_buffer + msg_buf_position, &buffer[buffer_pos], remaining_bytes);
- msg_buf_position += remaining_bytes;
+ buffer_len = [inputShlistStream read:(uint8_t *)header maxLength:6];
+ if (buffer_len != 6) {
+ [self error:@"read: didn't return 6 bytes"];
}
- // free temporary buffer, not msg_buffer
- free(buffer);
-}
-
-- (void) handle_complete_message
-{
- // assert msg_type_pos == 2 and msg_total_bytes_pos == 2 and msg_buf_position == msg_total_bytes
-
- if (msg_type == 0) {
- // registration response message
- if ([[NSFileManager defaultManager] fileExistsAtPath:device_id_file]) {
- // it would be strange if we got back a registration
- // message type when we already have a key file
- [self error:@"network: register: not overwriting key file with '%@'", msg_string];
- return;
- }
+ uint16_t version = ntohs(header[0]);
+ uint16_t msg_type = ntohs(header[1]);
+ uint16_t payload_size = ntohs(header[2]);
- [self info:@"network: register: writing new key '%@' to disk", msg_string];
- [msg_data writeToFile:device_id_file atomically:YES];
-
- // set this so we're ready to send other message types
- device_id = msg_data;
-
- // do a bulk list update
- [self send_message:3 contents:nil];
+ if (version != 0) {
+ [self error:@"read: invalid version %i", version];
+ }
+ if (msg_type > 10) {
+ [self error:@"read: invalid message type %i", msg_type];
+ }
+ if (payload_size > 4095) {
+ [self error:@"read: %i bytes payload too large", payload_size];
+ }
+ if (payload_size == 0) {
+ // Payload doesn't contain anything, that's ok
+ return;
}
- else if (msg_type == 1) {
- NSArray *fields = [msg_string componentsSeparatedByString:@"\0"];
- if ([fields count] != 3) {
- [self warn:@"network: new list response has invalid number of fields %i",
- [fields count]];
- return;
- }
+ const char *payload = malloc(payload_size);
+ buffer_len = [inputShlistStream read:(uint8_t *)payload maxLength:payload_size];
+ if (buffer_len != payload_size) {
+ [self error:@"read: expected %i byte payload but got %i", payload_size, buffer_len];
+ return;
+ }
+ [self info:@"read: payload is %i bytes", buffer_len];
- SharedList *shlist = [[SharedList alloc] init];
- shlist.id = [[fields objectAtIndex:0] dataUsingEncoding:NSUTF8StringEncoding];
- shlist.name = [fields objectAtIndex:1];
- shlist.members_phone_nums = [NSArray arrayWithObjects:[fields objectAtIndex:2], nil];
- shlist.items_ready = 0;
- shlist.items_total = 0;
+ NSData *data = [NSData dataWithBytes:payload length:payload_size];
- if ([self check_tvc:shlist_tvc])
- [shlist_tvc finished_new_list_request:shlist];
+ NSError *error = nil;
+ NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data
+ options:NSJSONReadingAllowFragments error:&error];
+ if (error) {
+ NSLog(@"%@", [error userInfo]);
+ };
- [self info:@"network: response for new list '%@' has %i fields",
- shlist.name, [fields count]];
+ NSString *status = [response objectForKey:@"status"];
+ if (status == nil) {
+ NSLog(@"read: response did not contain 'status' key");
+ return;
+ }
+ if ([status compare:@"err"] == 0) {
+ NSLog(@"read: response error, reason = '%@'", [response objectForKey:@"reason"]);
+ return;
}
- else if (msg_type == 3) {
- [self handle_bulk_list_update:msg_string];
-
- if ([self check_tvc:shlist_tvc])
- [shlist_tvc.tableView reloadData];
+ if (msg_type == device_add) {
+ [self device_add:response];
+ } else if (msg_type == list_add) {
+ [self list_add:response];
+ } else if (msg_type == lists_get) {
+ [self lists_get:response];
+ } else if (msg_type == list_join) {
+ [self list_join:response];
}
- else if (msg_type == 4) {
- SharedList *shlist = [[SharedList alloc] init];
- // XXX: sanitize msg_data, should be base64 and 43 bytes long
- shlist.id = msg_data;
+ // free((void *)payload);
+}
- // XXX: these need to be sent from the server
- shlist.items_ready = 0;
- shlist.items_total = 99;
- // shlist.list_name = <network>;
- // shlist.members = <network>;
+- (void) device_add:(NSDictionary *)response
+{
+ device_id = [response objectForKey:@"device_id"];
- if ([self check_tvc:shlist_tvc])
- [shlist_tvc finished_join_list_request:shlist];
- [self info:@"join list: response '%@' acknowledgedd", msg_string];
- }
+ [self info:@"device_add: writing new key '%@' to file", device_id];
+ NSError *error = nil;
+ [device_id writeToFile:device_id_file atomically:YES encoding:NSUTF8StringEncoding error:&error];
- else if (msg_type == 5) {
+ if (error != nil)
+ NSLog(@"%@", [error userInfo]);
+}
- NSArray *fields = [msg_string componentsSeparatedByString:@"\0"];
- if ([fields count] != 2) {
- [self warn:@"leave list: response had wrong number (%i) of fields",
- [fields count]];
- return;
- }
+- (void) list_add:(NSDictionary *)response
+{
+ NSDictionary *list = [response objectForKey:@"list"];
- SharedList *shlist = [[SharedList alloc] init];
- shlist.id = [[fields objectAtIndex:0] dataUsingEncoding:NSUTF8StringEncoding];
+ SharedList *shlist = [[SharedList alloc] init];
+ shlist.num = [list objectForKey:@"num"];
+ shlist.name = [list objectForKey:@"name"];
- // XXX: these need to be sent from the server
- // shlist.list_name = <network>;
- // shlist.members = <network>;
+ NSArray *members = [list objectForKey:@"members"];
+ shlist.members_phone_nums = members;
+ shlist.items_ready = [list objectForKey:@"items_complete"];
+ shlist.items_total = [list objectForKey:@"items_total"];
- if ([self check_tvc:shlist_tvc])
- [shlist_tvc finished_leave_list_request:shlist];
- [self info:@"leave list: response '%@' acknowledgedd", msg_string];
- }
-}
+ if ([self check_tvc:shlist_tvc])
+ [shlist_tvc finished_new_list_request:shlist];
-- (bool) check_tvc:(MainTableViewController *) tvc
-{
- if (tvc)
- return true;
- [self warn:@"network: trying to update main_tvc before it's ready, ignoring!"];
- return false;
+ [self info:@"list_add: successfully added new list '%@'", shlist.name];
}
-- (void) handle_bulk_list_update:(NSString *)raw_data
+- (void) lists_get:(NSDictionary *)response
{
+ NSArray *lists = [response objectForKey:@"lists"];
+ NSLog(@"lists_get: got %i lists from server", [lists count]);
+ // Don't attempt to update a view controller that isn't there yet
if (![self check_tvc:shlist_tvc])
return;
- // split over double \0
- NSArray *list_types = [raw_data componentsSeparatedByString:@"\0\0"];
- if ([list_types count] != 2) {
- [self warn:@"bulk list update: 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];
- }
-
- [self info:@"bulk list update: %i/%i your lists/other lists",
- [shlist_tvc.shared_lists count], [shlist_tvc.indirect_lists count]];
+ if (shlist_tvc)
+ [shlist_tvc lists_get_finished:lists];
}
-- (NSArray *) parse_lists:(NSString *)raw_lists
+- (void) list_join:(NSDictionary *)response
{
- // 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) {
- [self warn:@"parse list: less than 3 fields found: %i", field_count];
-
- // can't do anything with this list
- continue;
- }
- [self debug:@"parse_list: '%@' has %i fields",
- [list_fields objectAtIndex:0], field_count];
-
- // we've got everything we need
- SharedList *shared_list = [[SharedList alloc] init];
+ SharedList *shlist = [[SharedList alloc] init];
+ shlist.num = [response objectForKey:@"num"];
+
+ // XXX: these need to be sent from the server
+ // shlist.items_ready = 0;
+ // shlist.items_total = 99;
+ // shlist.list_name = <network>;
+ // shlist.members = <network>;
+
+ if ([self check_tvc:shlist_tvc])
+ [shlist_tvc finished_join_list_request:shlist];
+ [self info:@"list_join: joined list %i", shlist.num];
+}
- shared_list.name = [list_fields objectAtIndex:0];
- shared_list.id = [[list_fields objectAtIndex:1] dataUsingEncoding:NSUTF8StringEncoding];
- shared_list.members_phone_nums = [list_fields subarrayWithRange:NSMakeRange(2, field_count - 2)];
+- (void) list_leave:(NSDictionary *)response
+{
+ SharedList *shlist = [[SharedList alloc] init];
+ shlist.num = [response objectForKey:@"num"];
- // 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;
+ // XXX: these need to be sent from the server
+ // shlist.list_name = <network>;
+ // shlist.members = <network>;
- [output addObject:shared_list];
- }
+ if ([self check_tvc:shlist_tvc])
+ [shlist_tvc finished_leave_list_request:shlist];
+ [self info:@"list_leave: left list", shlist.num];
+}
- return output;
+- (bool) check_tvc:(MainTableViewController *) tvc
+{
+ if (tvc)
+ return true;
+ [self warn:@"network: trying to update main_tvc before it's ready, ignoring!"];
+ return false;
}
#define LOG_LEVEL_ERROR 0
diff --git a/ios/shlist/NewListTableViewController.m b/ios/shlist/NewListTableViewController.m
@@ -78,10 +78,17 @@
shared_list.deadline = _deadline_switch.isOn;
// _shared_list.filters = ???
- NSLog(@"debug: %@: saving", shared_list.name);
+ NSLog(@"new_list: sending list_add request...");
- NSData *payload = [shared_list.name dataUsingEncoding:NSUTF8StringEncoding];
- [network_connection send_message:1 contents:payload];
+ NSMutableDictionary *list = [[NSMutableDictionary alloc] init];
+ [list setObject:[NSNumber numberWithInt:0] forKey:@"num"];
+ [list setObject:shared_list.name forKey:@"name"];
+ [list setObject:[NSNumber numberWithInt:0] forKey:@"date"];
+
+ NSMutableDictionary *request = [[NSMutableDictionary alloc] init];
+ [request setObject:list forKey:@"list"];
+
+ [network_connection send_message:list_add contents:request];
}
@end
\ No newline at end of file
diff --git a/ios/shlist/SettingsTableViewController.h b/ios/shlist/SettingsTableViewController.h
@@ -0,0 +1,7 @@
+#import <UIKit/UIKit.h>
+
+@interface SettingsTableViewController : UITableViewController
+
+- (void) finish_ok_request;
+
+@end
diff --git a/ios/shlist/SettingsTableViewController.m b/ios/shlist/SettingsTableViewController.m
@@ -0,0 +1,55 @@
+#import "SettingsTableViewController.h"
+
+#import "Network.h"
+
+@interface SettingsTableViewController () {
+ Network *netconn;
+}
+
+@property (weak, nonatomic) IBOutlet UILabel *phone_number_label;
+@property (weak, nonatomic) IBOutlet UILabel *device_id_label;
+@property (weak, nonatomic) IBOutlet UILabel *network_label;
+
+@end
+
+@implementation SettingsTableViewController
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ netconn = [Network shared_network_connection];
+ NSString *device_id = [[NSString alloc] initWithData:[netconn get_device_id] encoding:NSASCIIStringEncoding];
+ _device_id_label.text = [device_id substringToIndex:8];
+}
+
+- (void) viewWillAppear:(BOOL)animated
+{
+ // check every time this view is selected
+ _network_label.text = @"Checking...";
+ netconn->settings_tvc = self;
+ [netconn send_message:8 contents:nil];
+}
+
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+- (void) finish_ok_request
+{
+ _network_label.text = @"All good";
+}
+
+/*
+#pragma mark - Navigation
+
+// 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.
+}
+*/
+
+@end