Localized sign up messages and gist log upload

This commit is contained in:
Frederic Jacobs 2014-07-03 03:12:34 +02:00
parent dca3c74bc3
commit 2a58c03b9f
11 changed files with 247 additions and 18 deletions

View File

@ -380,6 +380,7 @@
A1C32D5017A06538000A904E /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C32D4F17A06537000A904E /* AddressBookUI.framework */; };
A1C32D5117A06544000A904E /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C32D4D17A0652C000A904E /* AddressBook.framework */; };
AA0C8E498E2046B0B81EEE6E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313AE91B4954215858A5662 /* libPods.a */; };
B62686301964AE3D00D2D697 /* LogSubmit.m in Sources */ = {isa = PBXBuildFile; fileRef = B626862F1964AE3D00D2D697 /* LogSubmit.m */; };
B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; };
B6B6C3C71919440C00C0B76B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6B6C3C51919440C00C0B76B /* Localizable.strings */; };
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
@ -1087,6 +1088,8 @@
A1C32D4D17A0652C000A904E /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; };
A1C32D4F17A06537000A904E /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; };
A1FDCBEE16DAA6C300868894 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
B626862E1964AE3D00D2D697 /* LogSubmit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogSubmit.h; sourceTree = "<group>"; };
B626862F1964AE3D00D2D697 /* LogSubmit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogSubmit.m; sourceTree = "<group>"; };
B657DDC91911A40500F45B0C /* Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Signal.entitlements; sourceTree = "<group>"; };
B67EBF5C19194AC60084CCFD /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = SettingsBundle/Settings.bundle; sourceTree = SOURCE_ROOT; };
B6B6C3C61919440C00C0B76B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -1951,6 +1954,8 @@
76EB04B518170B33006006FC /* DecayingSampleEstimator.m */,
76EB04B618170B33006006FC /* EventWindow.h */,
76EB04B718170B33006006FC /* EventWindow.m */,
B626862E1964AE3D00D2D697 /* LogSubmit.h */,
B626862F1964AE3D00D2D697 /* LogSubmit.m */,
76EB04B818170B33006006FC /* LoggingUtil.h */,
76EB04B918170B33006006FC /* LoggingUtil.m */,
76EB04BA18170B33006006FC /* protocols */,
@ -3033,6 +3038,7 @@
70B8010C190C55660042E3F0 /* AbstractMessage.m in Sources */,
E197B61618BBEC1A00F073E5 /* StretchFactorController.m in Sources */,
76EB065018170B34006006FC /* DialerViewController.m in Sources */,
B62686301964AE3D00D2D697 /* LogSubmit.m in Sources */,
701231B518ECAA4500D456C4 /* EvpMessageDigest.m in Sources */,
76EB062218170B33006006FC /* CyclicalBuffer.m in Sources */,
76EB063C18170B33006006FC /* NumberUtil.m in Sources */,

View File

@ -1,8 +1,14 @@
#import <UIKit/UIKit.h>
#import "FutureSource.h"
#pragma mark Logging - Production logging wants us to write some logs to a file in case we need it for debugging.
#import <CocoaLumberjack/DDTTYLogger.h>
#import <CocoaLumberjack/DDFileLogger.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, readonly) DDFileLogger *fileLogger;
@end

View File

@ -16,11 +16,6 @@
#import "Util.h"
#import <UICKeyChainStore/UICKeyChainStore.h>
#pragma mark Logging - Production logging wants us to write some logs to a file in case we need it for debugging.
#import <CocoaLumberjack/DDTTYLogger.h>
#import <CocoaLumberjack/DDFileLogger.h>
#define kSignalVersionKey @"SignalUpdateVersionKey"
#ifdef __APPLE__
@ -31,6 +26,7 @@
@property (nonatomic, strong) MMDrawerController *drawerController;
@property (nonatomic, strong) NotificationTracker *notificationTracker;
@property (nonatomic) DDFileLogger *fileLogger;
@end
@ -75,13 +71,14 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[DDLog addLogger:[DDTTYLogger sharedInstance]];
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling.
fileLogger.logFileManager.maximumNumberOfLogFiles = 3; // Keep three days of logs.
[DDLog addLogger:fileLogger];
self.fileLogger = [[DDFileLogger alloc] init]; //Logging to file, because it's in the Cache folder, they are not uploaded in iTunes/iCloud backups.
self.fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling.
self.fileLogger.logFileManager.maximumNumberOfLogFiles = 3; // Keep three days of logs.
[DDLog addLogger:self.fileLogger];
[self performUpdateCheck];
[self disableCallLogBackup];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.notificationTracker = [NotificationTracker notificationTracker];
@ -102,8 +99,7 @@
leftSideMenuViewController.centerTabBarViewController.inboxFeedViewController.apnId = futureApnIdSource;
leftSideMenuViewController.centerTabBarViewController.settingsViewController.apnId = futureApnIdSource;
self.drawerController = [[MMDrawerController alloc] initWithCenterViewController:leftSideMenuViewController.centerTabBarViewController
leftDrawerViewController:leftSideMenuViewController];
self.drawerController = [[MMDrawerController alloc] initWithCenterViewController:leftSideMenuViewController.centerTabBarViewController leftDrawerViewController:leftSideMenuViewController];
self.window.rootViewController = _drawerController;
[self.window makeKeyAndVisible];

View File

@ -102,6 +102,18 @@
#define SETTINGS_LOG_CLEAR_MESSAGE NSLocalizedString(@"SETTINGS_LOG_CLEAR_MESSAGE", @"")
#define SETTINGS_LOG_CLEAR_CONFIRM NSLocalizedString(@"OK", @"")
#define SETTINGS_SENDLOG NSLocalizedString(@"SETTINGS_SENDLOG", @"")
#define SETTINGS_SENDLOG_WAITING NSLocalizedString(@"SETTINGS_SENDLOGS_WAITING", @"")
#define SETTINGS_SENDLOG_ALERT_TITLE NSLocalizedString(@"SETTINGS_SENDLOG_ALERT_TITLE", @"")
#define SETTINGS_SENDLOG_ALERT_BODY NSLocalizedString(@"SETTINGS_SENDLOG_ALERT_BODY",@"")
#define SETTINGS_SENDLOG_ALERT_PASTE NSLocalizedString(@"SETTINGS_SENDLOG_ALERT_PASTE", @"")
#define SETTINGS_SENDLOG_ALERT_EMAIL NSLocalizedString(@"SETTINGS_SENDLOG_ALERT_EMAIL", @"")
#define SETTINGS_SENDLOG_FAILED_TITLE NSLocalizedString(@"SETTINGS_SENDLOG_FAILED_TITLE", @"")
#define SETTINGS_SENDLOG_FAILED_BODY NSLocalizedString(@"SETTINGS_SENDLOG_FAILED_BODY", @"")
#define SETTINGS_SENDLOG_FAILED_DISMISS NSLocalizedString(@"OK", @"")
#pragma mark - Registration
#define REGISTER_CC_ERR_ALERT_VIEW_TITLE NSLocalizedString(@"REGISTER_CC_ERR_ALERT_VIEW_TITLE", @"")

View File

@ -0,0 +1,19 @@
//
// LogSubmit.h
// Signal
//
// Created by Frederic Jacobs on 02/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface LogSubmit : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
typedef void (^successBlock)(BOOL success, NSString *urlString);
+(void)submitLogsWithCompletion:(successBlock)block;
@property (nonatomic)NSMutableData *responseData;
@end

View File

@ -0,0 +1,114 @@
//
// LogSubmit.m
// Signal
//
// Created by Frederic Jacobs on 02/07/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
//
#import "LogSubmit.h"
#import "AppDelegate.h"
#include <sys/types.h>
#include <sys/sysctl.h>
@interface LogSubmit ()
@property (nonatomic, copy)successBlock block;
@end
@implementation LogSubmit
+(void)submitLogsWithCompletion:(successBlock)block{
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
NSArray *fileNames = delegate.fileLogger.logFileManager.sortedLogFileNames;
NSArray *filePaths = delegate.fileLogger.logFileManager.sortedLogFilePaths;
NSMutableDictionary *gistFiles = [@{} mutableCopy];
for (unsigned int i = 0; i < [filePaths count]; i++) {
[gistFiles setObject:@{@"content":[NSString stringWithContentsOfFile:[filePaths objectAtIndex:i] encoding:NSUTF8StringEncoding error:nil]} forKey:[fileNames objectAtIndex:i]];
}
NSDictionary *gistDict = @{@"description":[self gistDescription], @"files":gistFiles};
NSData *postData = [NSJSONSerialization dataWithJSONObject:gistDict options:0 error:nil];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:@"https://api.github.com/gists"] cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:30];
[[self sharedManager] setResponseData:[NSMutableData data]];
[[self sharedManager] setBlock:block];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:[self sharedManager]];
[connection start];
}
+ (id)sharedManager {
static LogSubmit *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
- (id)init {
if (self = [super init]) {
self.responseData = [NSMutableData data];
}
return self;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:0 error:&error];
if (!error) {
self.block(true, [dict objectForKey:@"html_url"]);
} else{
DDLogError(@"Error on debug response: %@", error);
self.block(false, nil);
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
DDLogError(@"Uploading logs failed with error: %@", error);
self.block(false,nil);
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
if ( [httpResponse statusCode] != 201) {
DDLogError(@"Failed to submit debug log: %@", httpResponse.debugDescription);
self.block(false,nil);
}
}
+(NSString*)gistDescription{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithUTF8String:machine];
free(machine);
NSString *gistDesc = [NSString stringWithFormat:@"iPhone Version: %@, iOS Version: %@", platform,[UIDevice currentDevice].systemVersion];
return gistDesc;
}
@end

View File

@ -128,7 +128,7 @@
andErrorHandler:[Environment errorNoter]];
};
Future *futurePhoneRegistrationStarted = [AsyncUtil raceCancellableOperation:regStarter
againstTimeout:30.0
againstTimeout:20.0
untilCancelled:cancelToken];
Future *futurePhoneRegistrationVerified = [futurePhoneRegistrationStarted then:^(id _) {
@ -201,13 +201,13 @@
if ([error isKindOfClass:[HttpResponse class]]) {
HttpResponse* badResponse = error;
if ([badResponse getStatusCode] == 401) {
#warning localize this alert
UIAlertView *incorrectChallengeCodeAV = [[UIAlertView alloc]initWithTitle:@"Registration error" message:@"The challenge code you entered is incorrect." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[incorrectChallengeCodeAV show];
return;
}
}
[Environment errorNoter](error, @"While Verifying Challenge.", NO);
#warning add implementation
}];
[futureDone thenDo:^(id result) {

View File

@ -14,7 +14,7 @@
*
*/
@interface SettingsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@interface SettingsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIAlertViewDelegate>
@property (nonatomic, strong) IBOutlet UITableView *settingsTableView;
@property (nonatomic, strong) IBOutlet UILabel *phoneNumberLabel;
@ -39,6 +39,7 @@
@property (nonatomic, strong) IBOutlet UITableViewCell *directoryUpdateCell;
@property (nonatomic, strong) IBOutlet UIButton *sendFeedbackButton;
@property (nonatomic, strong) IBOutlet UITableViewCell *sendDebugLog;
@property (nonatomic, assign) FutureSource *apnId;

View File

@ -8,6 +8,7 @@
#import "RecentCallManager.h"
#import "RegisterViewController.h"
#import "SettingsViewController.h"
#import "LogSubmit.h"
#import "UIViewController+MMDrawerController.h"
@ -24,6 +25,8 @@ static NSString *const CHECKBOX_EMPTY_IMAGE_NAME = @"checkbox_empty";
NSArray *_privacyTableViewCells;
NSArray *_localizationTableViewCells;
NSArray *_callQualityTableViewCells;
NSString *gistURL;
}
@end
@ -145,7 +148,8 @@ static NSString *const CHECKBOX_EMPTY_IMAGE_NAME = @"checkbox_empty";
return @[_hideContactImagesCell,
_disableAutocorrectCell,
_disableHistoryCell,
_clearHistoryLogCell];
_clearHistoryLogCell,
_sendDebugLog];
}
- (NSArray *)localizationCells {
@ -295,6 +299,44 @@ static NSString *const CHECKBOX_EMPTY_IMAGE_NAME = @"checkbox_empty";
if (cell == _dateFormatCell) {
[self showDateFormatPicker];
}
if (cell == _sendDebugLog) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SETTINGS_SENDLOG_WAITING
message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil];
[alert show];
[LogSubmit submitLogsWithCompletion:^(BOOL success, NSString *urlString) {
[alert dismissWithClickedButtonIndex:0 animated:YES];
if (success) {
gistURL = urlString;
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:SETTINGS_SENDLOG_ALERT_TITLE message:SETTINGS_SENDLOG_ALERT_BODY delegate:self cancelButtonTitle:SETTINGS_SENDLOG_ALERT_PASTE otherButtonTitles:SETTINGS_SENDLOG_ALERT_EMAIL, nil];
[alertView show];
} else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:SETTINGS_SENDLOG_FAILED_TITLE message:SETTINGS_SENDLOG_FAILED_BODY delegate:nil cancelButtonTitle:SETTINGS_SENDLOG_FAILED_DISMISS otherButtonTitles:nil, nil];
[alertView show];
}
}];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
[self pasteBoardCopy:gistURL];
} else{
[self submitEmail:gistURL];
}
}
- (void)submitEmail:(NSString*)url{
NSString *urlString = [NSString stringWithString: [@"mailto:support@whispersystems.org?subject=iOS%20Debug%20Log&body=" stringByAppendingString:[[NSString stringWithFormat:@"Log URL: %@ \n Tell us about the issue: ", url]stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]];
[[UIApplication sharedApplication] openURL: [NSURL URLWithString: urlString]];
}
- (void)pasteBoardCopy:(NSString*)url{
UIPasteboard *pb = [UIPasteboard generalPasteboard];
[pb setString:url];
}
- (void)findAndLocalizeLabelsForView:(UIView *)view {

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="13A603" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SettingsViewController">
@ -21,6 +21,7 @@
<outlet property="locationOverridesHeaderView" destination="9Ou-py-Aq1" id="nC3-ta-AyD"/>
<outlet property="phoneNumberLabel" destination="G77-lz-XM0" id="adE-bu-2Kn"/>
<outlet property="privacyAndSecurityHeaderView" destination="XIa-5u-rk1" id="kap-XQ-9AL"/>
<outlet property="sendDebugLog" destination="Yc0-ZL-RM6" id="wyq-HF-B9c"/>
<outlet property="sendFeedbackButton" destination="cqe-Lt-yoW" id="yOB-Zk-xpw"/>
<outlet property="settingsTableView" destination="ajL-B0-V0M" id="0zr-QP-yQl"/>
<outlet property="titleLabel" destination="X1p-jb-cMh" id="Duc-Ac-qHm"/>
@ -556,6 +557,30 @@
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="SettingsTableViewCell" id="Yc0-ZL-RM6">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Yc0-ZL-RM6" id="S9z-bI-5FI">
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Submit Debug Log" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cPQ-gV-EF9" customClass="HelveticaNeueLTStdMedLabel">
<rect key="frame" x="20" y="11" width="223" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="localizationKey" value="SETTINGS_SENDLOG"/>
</userDefinedRuntimeAttributes>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rLV-oR-lWh" userLabel="Seperator View">
<rect key="frame" x="15" y="42" width="290" height="1"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.7843137255" green="0.7843137255" blue="0.7843137255" alpha="1" colorSpace="calibratedRGB"/>
</view>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</objects>
<resources>
<image name="checkbox_empty.png" width="19" height="19"/>
@ -564,4 +589,4 @@
<image name="volume_high.png" width="19" height="19"/>
<image name="volume_low.png" width="12" height="12"/>
</resources>
</document>
</document>

View File

@ -121,6 +121,14 @@
"SETTINGS_NUMBER_PREFIX" = "Your Number:";
"SETTINGS_PRIVACY_AND_SECURITY" = "Privacy and Security";
"SETTINGS_RINGTONE" = "Ringtone";
"SETTINGS_SENDLOG" = "Submit Debug Log";
"SETTINGS_SENDLOGS_WAITING" = "Sending anonymized log file\n Please wait...";
"SETTINGS_SENDLOG_ALERT_TITLE" = "Submit debug log";
"SETTINGS_SENDLOG_ALERT_BODY" = "Do you want to copy the log URL to the pasteboard or submit it by email?";
"SETTINGS_SENDLOG_ALERT_PASTE" = "Pasteboard";
"SETTINGS_SENDLOG_ALERT_EMAIL" = "Email";
"SETTINGS_SENDLOG_FAILED_TITLE" = "Failed to submit debug log";
"SETTINGS_SENDLOG_FAILED_BODY" = "The debug log could not be submitted. Please try again.";
"SETTINGS_VIBRATE_ON_RING" = "Vibrate on Ring";
"SETTINGS_VIBRATE_ON_SILENT" = "Vibrate on Silent";
"SPEAKER_BUTTON_TITLE" = "Speaker";