commit 94668258c864cec02b1df5cf70a91add0940c226
parent 692db950ba76575d2a2cbf590669f02a80f2766e
Author: Kyle Milz <kyle@Kyles-MacBook-Pro.local>
Date: Sun, 20 Sep 2015 12:19:08 -0600
ios: get a phone number popup dialog going
Diffstat:
4 files changed, 141 insertions(+), 101 deletions(-)
diff --git a/ios-ng/ContactsTableViewController.m b/ios-ng/ContactsTableViewController.m
@@ -51,9 +51,10 @@
[_cells addObject:[letter_to_contact_map objectForKey:letter]];
}
-- (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
+- (void)didReceiveMemoryWarning
+{
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
@@ -67,7 +68,6 @@
return [[_cells objectAtIndex:section] count];
}
-
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
diff --git a/ios-ng/shlist/MainTableViewController.m b/ios-ng/shlist/MainTableViewController.m
@@ -7,7 +7,9 @@
#import <AddressBook/AddressBook.h>
#include "libkern/OSAtomic.h"
-@interface MainTableViewController ()
+@interface MainTableViewController () {
+ NSString *phone_num_file;
+}
@property (strong, nonatomic) Network *server;
@property NSMutableDictionary *phnum_to_name_map;
@@ -26,37 +28,89 @@
// display an Edit button in the navigation bar for this view controller
self.navigationItem.leftBarButtonItem = self.editButtonItem;
+ // main lists
self.shared_lists = [[NSMutableArray alloc] init];
self.indirect_lists = [[NSMutableArray alloc] init];
- // first thing we need is a phone number, can't even send registration without it
- // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- // NSString *documentsDirectory = [paths objectAtIndex:0];
- // NSString *phone_num_file = [documentsDirectory stringByAppendingPathComponent:@"phone_num"];
- _phone_number = @"4037082094";
+ // store the path to the phone number file
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ phone_num_file = [documentsDirectory stringByAppendingPathComponent:@"phone_num"];
- // create one and only server instance, this gets passed around
_server = [[Network alloc] init];
_server->shlist_tvc = self;
- if ([_server prepare]) {
- NSLog(@"info: server connection prepared");
- // bulk update, doesn't take a payload
- [_server send_message:3 contents:nil];
- }
-
- // the capacity here assumes one phone number per person
_phnum_to_name_map = [[NSMutableDictionary alloc] init];
+ _phone_number = nil;
+ if ([self load_phone_number]) {
+ // phone number loaded, try loading device id
+ if ([_server load_device_id:[_phone_number dataUsingEncoding:NSASCIIStringEncoding]]) {
+ NSLog(@"info: network: connection ready");
+ // bulk update, doesn't take a payload
+ [_server send_message:3 contents:nil];
+ }
+ // else, device id request sent
+ }
+ // else, phone number entry is on screen
// get instance and wait for privacy window to clear
_address_book = [AddressBook shared_address_book];
_address_book.main_tvc = self;
}
+- (bool) load_phone_number
+{
+ if ([[NSFileManager defaultManager] fileExistsAtPath:phone_num_file]) {
+ // file exists, read what it has
+ // XXX: validate length of file too
+ _phone_number = [NSString stringWithContentsOfFile:phone_num_file];
+ return true;
+ }
+
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Important"
+ message:@"In order for us to calculate your mutual contacts, your phone number is needed."
+ delegate:self cancelButtonTitle:@"Nope" otherButtonTitles:@"Ok", nil];
+
+ alert.alertViewStyle = UIAlertViewStylePlainTextInput;
+
+ // it's a phone number, so only show the number pad
+ UITextField * alertTextField = [alert textFieldAtIndex:0];
+ alertTextField.keyboardType = UIKeyboardTypeNumberPad;
+ alertTextField.placeholder = @"Enter your phone number";
+
+ [alert show];
+ return false;
+}
+
+- (void)alertView:(UIAlertView *)alertView
+ clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ NSString *entered_phone_num = [[alertView textFieldAtIndex:0] text];
+ NSLog(@"warn: main: writing phone num '%@' to disk", entered_phone_num);
+ NSError *error;
+ [entered_phone_num writeToFile:phone_num_file atomically:YES encoding:NSASCIIStringEncoding error:&error];
+
+ if (error)
+ NSLog(@"warn: main: writing phone number file: %@", error);
+
+ if ([entered_phone_num compare:@""] == NSOrderedSame) {
+ NSLog(@"warn: load phone number: entered emtpy phone number");
+ }
+
+ _phone_number = entered_phone_num;
+
+ if ([_server load_device_id:[_phone_number dataUsingEncoding:NSASCIIStringEncoding]]) {
+ NSLog(@"info: network: connection ready");
+ // bulk update, doesn't take a payload
+ [_server send_message:3 contents:nil];
+ }
+ // else, device id request sent
+}
+
- (void) update_address_book
{
[_phnum_to_name_map removeAllObjects];
- // XXX: it'd be nice to resize the mutable array to num_contacts here
+ // XXX: it'd be nice to resize phnum_to_name_map to num_contacts here
for (Contact *contact in _address_book.contacts) {
NSString *disp_name;
@@ -292,7 +346,7 @@
if (name)
[members addObject:name];
- else if ([phone_number compare:_phone_number] == NSOrderedSame)
+ else if (_phone_number && ([_phone_number compare:phone_number] == NSOrderedSame))
[members addObject:@"You"];
else
// didn't find it, you don't know this person
diff --git a/ios-ng/shlist/Network.h b/ios-ng/shlist/Network.h
@@ -1,4 +1,5 @@
#import <UIKit/UIKit.h>
+
#import "MainTableViewController.h"
#import "ListTableViewController.h"
@@ -13,7 +14,7 @@
}
-- (bool) prepare;
+- (bool) load_device_id:(NSData*)phone_number;
- (void) send_message:(uint16_t)msg_type contents:(NSData *)data;
@end
\ No newline at end of file
diff --git a/ios-ng/shlist/Network.m b/ios-ng/shlist/Network.m
@@ -2,21 +2,21 @@
#import "DataStructures.h"
@interface Network () {
- NSData *msg_data;
- NSString *msg_string;
- uint8_t msg_buffer[1024];
- unsigned int msg_buf_position;
+ 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_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;
+ uint8_t msg_type_tmp[2];
+ unsigned short msg_type;
+ unsigned int msg_type_pos;
- int connected;
- NSData *device_id;
+ NSData *device_id;
+ NSString *device_id_file;
}
@end
@@ -26,7 +26,10 @@
- (id) init
{
if (self = [super init]) {
- connected = 0;
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ device_id_file = [documentsDirectory stringByAppendingPathComponent:@"shlist_key"];
+
msg_buf_position = 0;
msg_total_bytes = 0;
@@ -34,6 +37,7 @@
msg_type = 0;
msg_type_pos = 0;
+ [self connect];
}
return self;
@@ -59,48 +63,52 @@
[inputShlistStream open];
[outputShlistStream open];
- NSLog(@"info: network: finished connecting to absentmindedproductions.ca");
+ NSLog(@"info: network: bound to amp.ca");
}
-- (bool) prepare
+- (void) disconnect
{
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
+ [inputShlistStream close];
+ [outputShlistStream close];
- NSString *device_id_file = [documentsDirectory stringByAppendingPathComponent:@"shlist_key"];
+ [inputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
+ forMode:NSDefaultRunLoopMode];
+ [outputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
+ forMode:NSDefaultRunLoopMode];
- // NSError *error = nil;
- // [[NSFileManager defaultManager] removeItemAtPath:destinationPath error:&error];
+ inputShlistStream = nil; // stream is ivar, so reinit it
+ outputShlistStream = nil; // stream is ivar, so reinit it
+}
- // TODO: also check the length of the file
- if (![[NSFileManager defaultManager] fileExistsAtPath:device_id_file]) {
- // no device id file found, send a registration message
- NSMutableData *msg = [NSMutableData data];
+- (bool) load_device_id:(NSData *)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];
- // message type 0
- [msg appendBytes:"\x00\x00" length:2];
+ return true;
+ }
- // phone number length is 10
- uint16_t length_network = htons(10);
- [msg appendBytes:&length_network length:2];
+ // no device id file found, send a registration message
+ NSMutableData *msg = [NSMutableData data];
- // actual phone number
- const char *phone_number = "4037082094";
- [msg appendBytes:phone_number length:10];
+ // message type 0
+ uint16_t msg_type_network = htons(0);
+ [msg appendBytes:&msg_type_network length:2];
- if (connected == 0)
- [self connect];
- [outputShlistStream write:[msg bytes] maxLength:[msg length]];
- NSLog(@"info: sent registration message");
+ // phone number length is 10
+ uint16_t length_network = htons(10);
+ [msg appendBytes:&length_network length:2];
- // we don't have a device id so we can't do anything yet
- return false;
- }
+ // append phone number
+ [msg appendData:phone_number];
- // read device id from filesystem into memory
- device_id = [NSData dataWithContentsOfFile:device_id_file];
+ [outputShlistStream write:[msg bytes] maxLength:[msg length]];
+ NSLog(@"info: sent registration message");
- return true;
+ // we don't have a device id so we can't do anything yet
+ return false;
}
- (void) send_message:(uint16_t)send_msg_type contents:(NSData *)payload
@@ -125,12 +133,15 @@
[msg appendData:payload];
}
- if (connected == 0) {
- NSLog(@"info: network: not connected in send_message, reconnecting...");
+ if ([outputShlistStream write:[msg bytes] maxLength:[msg length]] == -1) {
+ NSLog(@"warn: network: write error occurred, reconnecting");
+ [self disconnect];
[self connect];
+
+ if ([outputShlistStream write:[msg bytes] maxLength:[msg length]] == -1) {
+ NSLog(@"warn: network: resend failed after reconnect, giving up");
+ }
}
- if ([outputShlistStream write:[msg bytes] maxLength:[msg length]] == -1)
- NSLog(@"warn: network: write error occurred");
}
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
@@ -146,7 +157,6 @@
break;
case NSStreamEventOpenCompleted:
NSLog(@"info: network: %@ stream opened", stream_name);
- connected = 1;
break;
case NSStreamEventHasBytesAvailable:
if (stream == inputShlistStream) {
@@ -163,27 +173,17 @@
NSLog(@"info: network: stream has space available");
break;
case NSStreamEventErrorOccurred:
+ // I saw this case when trying to connect to a down server
+
NSLog(@"info: network: stream error occurred");
- // I saw this case when trying to connect to a down server
+ [self disconnect];
// fall through on purpose
case NSStreamEventEndEncountered:
// close both sides of the connection on end
NSLog(@"ShlistServer::NSStreamEventEndEncountered");
- [inputShlistStream close];
- [outputShlistStream close];
-
- [inputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
- [outputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
- // [inputShlistStream release];
- // [outputShlistStream release];
-
- inputShlistStream = nil; // stream is ivar, so reinit it
- outputShlistStream = nil; // stream is ivar, so reinit it
- connected = 0;
+ [self disconnect];
break;
default:
@@ -322,11 +322,7 @@
if (msg_type == 0) {
// registration response message
-
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- NSString *destinationPath = [documentsDirectory stringByAppendingPathComponent:@"shlist_key"];
- if ([[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
+ 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
NSLog(@"error: network: register: not overwriting key file with '%@'", msg_string);
@@ -334,7 +330,7 @@
}
NSLog(@"info: network: register: writing new key '%@' to disk", msg_string);
- [msg_data writeToFile:destinationPath atomically:YES];
+ [msg_data writeToFile:device_id_file atomically:YES];
// set this so we're ready to send other message types
device_id = msg_data;
@@ -366,6 +362,7 @@
else if (msg_type == 3) {
[self handle_bulk_list_update:msg_string];
+ [shlist_tvc.tableView reloadData];
}
else if (msg_type == 4) {
@@ -430,8 +427,6 @@
NSArray *indirect_lists = [self parse_lists:my_friends_lists];
[shlist_tvc.indirect_lists addObjectsFromArray:indirect_lists];
}
-
- [shlist_tvc.tableView reloadData];
}
- (NSArray *) parse_lists:(NSString *)raw_lists
@@ -453,7 +448,6 @@
NSLog(@"info: parse_list: '%@' has %i fields",
[list_fields objectAtIndex:0], field_count);
-
// we've got everything we need
SharedList *shared_list = [[SharedList alloc] init];
@@ -475,16 +469,7 @@
- (void) dealloc
{
- [inputShlistStream close];
- [outputShlistStream close];
-
- [inputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
- [outputShlistStream removeFromRunLoop:[NSRunLoop currentRunLoop]
- forMode:NSDefaultRunLoopMode];
-
- inputShlistStream = nil; // stream is ivar, so reinit it
- outputShlistStream = nil; // stream is ivar, so reinit it
+ [self disconnect];
}
@end