├── .gitignore ├── Extension ├── Base.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── MainInterface.storyboard ├── Extension.entitlements ├── Info.plist ├── TodayViewController.h ├── TodayViewController.m ├── en.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── MainInterface.strings └── zh-Hans.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── MainInterface.strings ├── LICENSE ├── NetAsistant.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── NetAsistant ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── Info.plist │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.storyboard ├── Controllers │ ├── .DS_Store │ ├── SAAboutViewController.h │ ├── SAAboutViewController.m │ ├── SADetailViewController.h │ ├── SADetailViewController.m │ ├── SAInfoViewController.h │ ├── SAInfoViewController.m │ ├── SAMainViewController.h │ └── SAMainViewController.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── up&down1 3.png │ ├── Icon.imageset │ │ ├── Contents.json │ │ └── logo copy.png │ ├── IconClose.imageset │ │ ├── Contents.json │ │ └── IconClose.png │ ├── IconInfo.imageset │ │ ├── Contents.json │ │ └── IconInfo.png │ ├── IconMore.imageset │ │ ├── Contents.json │ │ └── IconMore.png │ ├── Step_1.imageset │ │ ├── Contents.json │ │ └── step1.png │ └── Step_2.imageset │ │ ├── Contents.json │ │ └── step2.png ├── LaunchScreen.xib ├── Libs │ ├── .DS_Store │ ├── Umeng │ │ ├── .DS_Store │ │ ├── MobClick.h │ │ └── libMobClickLibrary.a │ └── VVBlurPresentation │ │ ├── VVBlurPresentationController.h │ │ ├── VVBlurPresentationController.m │ │ ├── VVBlurPresenter.h │ │ ├── VVBlurPresenter.m │ │ ├── VVBlurTransitioning.h │ │ ├── VVBlurTransitioning.m │ │ ├── VVBlurViewController.h │ │ └── VVBlurViewController.m ├── Models │ ├── SADetail.h │ ├── SADetail.m │ ├── SANetworkFlow.h │ └── SANetworkFlow.m ├── NetAsistant.entitlements ├── Services │ ├── .DS_Store │ ├── SACoreDataManager.h │ ├── SACoreDataManager.m │ ├── SAGlobalHolder.h │ ├── SAGlobalHolder.m │ ├── SANetworkFlowService.h │ └── SANetworkFlowService.m ├── Utils │ ├── SAConvertUtils.h │ ├── SAConvertUtils.m │ ├── SADateUtils.h │ └── SADateUtils.m ├── Views │ ├── SADetailCell.h │ └── SADetailCell.m ├── en.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.strings ├── main.m ├── netasistant.xcdatamodeld │ └── netasistant.xcdatamodel │ │ └── contents └── zh-Hans.lproj │ ├── InfoPlist.strings │ ├── Localizable.strings │ └── Main.strings ├── NetAsistantTests ├── Info.plist └── NetAsistantTests.m ├── README.md ├── 上网助手 WatchKit App ├── Base.lproj │ └── Interface.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── 172.png │ │ ├── 196.png │ │ ├── 29@3x-1.png │ │ ├── 29@3x.png │ │ ├── 48.png │ │ ├── 55.png │ │ ├── 80.png │ │ ├── 88.png │ │ └── Contents.json └── Info.plist └── 上网助手 WatchKit Extension ├── GlanceController.h ├── GlanceController.m ├── Images.xcassets └── README__ignoredByTemplate__ ├── Info.plist ├── InterfaceController.h ├── InterfaceController.m └── 上网助手 WatchKit Extension.entitlements /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | -------------------------------------------------------------------------------- /Extension/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "上网助手"; 10 | "CFBundleName" = "上网助手"; -------------------------------------------------------------------------------- /Extension/Base.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "套餐总量: %@" = "套餐总量: %@"; -------------------------------------------------------------------------------- /Extension/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 55 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 82 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Extension/Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.netasistant 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleDisplayName 8 | 上网助手 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIcons 12 | 13 | CFBundleIcons~ipad 14 | 15 | CFBundleIdentifier 16 | com.zangzhiya.netasistant.extension 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | 上网助手 21 | CFBundlePackageType 22 | XPC! 23 | CFBundleShortVersionString 24 | 1.7 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 51 29 | LSHasLocalizedDisplayName 30 | 31 | NSExtension 32 | 33 | NSExtensionMainStoryboard 34 | MainInterface 35 | NSExtensionPointIdentifier 36 | com.apple.widget-extension 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Extension/TodayViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TodayViewController.h 3 | // Extension 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TodayViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Extension/TodayViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TodayViewController.m 3 | // Extension 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "TodayViewController.h" 10 | #import "SANetworkFlow.h" 11 | #import "SANetworkFlowService.h" 12 | #import "SAGlobalHolder.h" 13 | #import "SAConvertUtils.h" 14 | #import "SADateUtils.h" 15 | #import 16 | 17 | @interface TodayViewController () 18 | 19 | @property (weak, nonatomic) IBOutlet UILabel *usedFlowLabel; 20 | @property (weak, nonatomic) IBOutlet UILabel *limitFlowLabel; 21 | @property (weak, nonatomic) IBOutlet UILabel *unusedFlowLabel; 22 | @property (weak, nonatomic) IBOutlet UIView *progressView; 23 | @property (weak, nonatomic) IBOutlet UIView *progressHoverView; 24 | @property (weak, nonatomic) IBOutlet UIView *highlightView; 25 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *progressWith; 26 | 27 | @end 28 | 29 | @implementation TodayViewController 30 | 31 | - (void)viewDidLoad 32 | { 33 | [super viewDidLoad]; 34 | } 35 | 36 | - (void)didReceiveMemoryWarning 37 | { 38 | [super didReceiveMemoryWarning]; 39 | } 40 | 41 | - (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets 42 | { 43 | return UIEdgeInsetsZero; 44 | } 45 | 46 | - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler 47 | { 48 | completionHandler(NCUpdateResultNewData); 49 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 50 | NSDate *nowDate = [NSDate date]; 51 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 52 | if (holder.lastRecordDate && [SADateUtils monthWithDate:nowDate] != [SADateUtils monthWithDate:holder.lastRecordDate] 53 | && [nowDate timeIntervalSince1970] > [holder.lastRecordDate timeIntervalSince1970]) { 54 | [holder cleanFlowOfLastMonth]; 55 | } 56 | [self updateNetworkFlow]; 57 | [holder backupToFile]; 58 | }); 59 | } 60 | 61 | - (void)updateNetworkFlow 62 | { 63 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 64 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 65 | SANetworkFlow *networkFlow = [SANetworkFlowService networkFlow]; 66 | if (networkFlow) { 67 | [holder updateDataWithNetworkFlow:networkFlow]; 68 | dispatch_async(dispatch_get_main_queue(), ^{ 69 | self.usedFlowLabel.text = [SAConvertUtils bytesToString:holder.usedFlow]; 70 | self.limitFlowLabel.text = [NSString stringWithFormat:NSLocalizedString(@"套餐总量: %@", nil), [SAConvertUtils bytesToString:holder.packageFlow]]; 71 | self.unusedFlowLabel.text = [SAConvertUtils bytesToString:holder.remainedFlow]; 72 | CGFloat progressWidth = (CGFloat)holder.usedFlow / (CGFloat)holder.packageFlow * self.progressView.frame.size.width; 73 | if (progressWidth > self.progressView.frame.size.width) { 74 | progressWidth = self.progressView.frame.size.width; 75 | } 76 | self.progressWith.constant = progressWidth; 77 | NSInteger percent = (holder.packageFlow - holder.usedFlow) * 100.0f / holder.packageFlow; 78 | self.progressHoverView.backgroundColor = [holder colorWithPercent:percent]; 79 | [self.view layoutIfNeeded]; 80 | }); 81 | } 82 | }); 83 | } 84 | 85 | #pragma mark - Handler 86 | 87 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 88 | { 89 | self.highlightView.hidden = NO; 90 | } 91 | 92 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 93 | { 94 | self.highlightView.hidden = YES; 95 | } 96 | 97 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 98 | { 99 | self.highlightView.hidden = YES; 100 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 101 | [self.extensionContext openURL:[NSURL URLWithString:@"NetAsistant://"] completionHandler:nil]; 102 | }); 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /Extension/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "NetAssistant"; 10 | "CFBundleName" = "NetAssistant"; -------------------------------------------------------------------------------- /Extension/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "套餐总量: %@" = "Total: %@"; -------------------------------------------------------------------------------- /Extension/en.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "IBUILabel"; text = "套餐总量: 0KB"; ObjectID = "Bj7-dp-Ceb"; */ 3 | "Bj7-dp-Ceb.text" = "Total: 0KB"; 4 | 5 | /* Class = "IBUILabel"; text = "0KB"; ObjectID = "X3r-q9-Zt7"; */ 6 | "X3r-q9-Zt7.text" = "0KB"; 7 | 8 | /* Class = "IBUILabel"; text = "0KB"; ObjectID = "XXt-5a-Gb6"; */ 9 | "XXt-5a-Gb6.text" = "0KB"; 10 | 11 | /* Class = "IBUILabel"; text = "剩余:"; ObjectID = "dBy-tj-0si"; */ 12 | "dBy-tj-0si.text" = "Left:"; 13 | 14 | /* Class = "IBUILabel"; text = "已用:"; ObjectID = "rBd-4S-aMT"; */ 15 | "rBd-4S-aMT.text" = "Used:"; 16 | -------------------------------------------------------------------------------- /Extension/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "上网助手"; 10 | "CFBundleName" = "上网助手"; -------------------------------------------------------------------------------- /Extension/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localizable.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "套餐总量: %@" = "套餐总量: %@"; -------------------------------------------------------------------------------- /Extension/zh-Hans.lproj/MainInterface.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "IBUILabel"; text = "套餐总量: 0KB"; ObjectID = "Bj7-dp-Ceb"; */ 3 | "Bj7-dp-Ceb.text" = "套餐总量: 0KB"; 4 | 5 | /* Class = "IBUILabel"; text = "0KB"; ObjectID = "X3r-q9-Zt7"; */ 6 | "X3r-q9-Zt7.text" = "0KB"; 7 | 8 | /* Class = "IBUILabel"; text = "0KB"; ObjectID = "XXt-5a-Gb6"; */ 9 | "XXt-5a-Gb6.text" = "0KB"; 10 | 11 | /* Class = "IBUILabel"; text = "剩余:"; ObjectID = "dBy-tj-0si"; */ 12 | "dBy-tj-0si.text" = "剩余:"; 13 | 14 | /* Class = "IBUILabel"; text = "已用:"; ObjectID = "rBd-4S-aMT"; */ 15 | "rBd-4S-aMT.text" = "已用:"; 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Chihya Tsang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /NetAsistant.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NetAsistant/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /NetAsistant/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "SAGlobalHolder.h" 11 | #import "SANetworkFlowService.h" 12 | #import "SANetworkFlow.h" 13 | #import "MobClick.h" 14 | #import "SACoreDataManager.h" 15 | 16 | @interface AppDelegate () 17 | 18 | @end 19 | 20 | @implementation AppDelegate 21 | 22 | 23 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 24 | { 25 | application.statusBarHidden = NO; 26 | [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum]; 27 | [MobClick startWithAppkey:@"54f041e7fd98c5f4e80001b4"]; 28 | NSString *version = [[NSBundle mainBundle].infoDictionary objectForKey:@"CFBundleShortVersionString"]; 29 | [MobClick setAppVersion:version]; 30 | [MobClick setEncryptEnabled:YES]; 31 | return YES; 32 | } 33 | 34 | - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 35 | { 36 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 37 | SANetworkFlow *networkFlow = [SANetworkFlowService networkFlow]; 38 | if (networkFlow) { 39 | [holder updateDataWithNetworkFlow:networkFlow]; 40 | [holder backupToFile]; 41 | } 42 | completionHandler(UIBackgroundFetchResultNewData); 43 | } 44 | 45 | - (void)applicationWillResignActive:(UIApplication *)application 46 | { 47 | [[SAGlobalHolder sharedSingleton] backupToFile]; 48 | } 49 | 50 | - (void)applicationDidEnterBackground:(UIApplication *)application 51 | { 52 | [[SACoreDataManager manager] saveContext]; 53 | } 54 | 55 | - (void)applicationWillEnterForeground:(UIApplication *)application 56 | { 57 | } 58 | 59 | - (void)applicationDidBecomeActive:(UIApplication *)application 60 | { 61 | } 62 | 63 | - (void)applicationWillTerminate:(UIApplication *)application 64 | { 65 | [[SACoreDataManager manager] saveContext]; 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /NetAsistant/Base.lproj/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.zangzhiya.netasistant 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | 上网助手 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.7 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLName 27 | NetAsistant 28 | CFBundleURLSchemes 29 | 30 | NetAsistant 31 | 32 | 33 | 34 | CFBundleVersion 35 | 51 36 | LSRequiresIPhoneOS 37 | 38 | UIBackgroundModes 39 | 40 | fetch 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UIStatusBarHidden 51 | 52 | UIStatusBarStyle 53 | UIStatusBarStyleLightContent 54 | UISupportedInterfaceOrientations 55 | 56 | UIInterfaceOrientationPortrait 57 | 58 | UIViewControllerBasedStatusBarAppearance 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /NetAsistant/Base.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "上网助手"; 10 | "CFBundleName" = "上网助手"; -------------------------------------------------------------------------------- /NetAsistant/Base.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localization.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | //邮件反馈 10 | "设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容" = "设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容"; 11 | "用户反馈" = "用户反馈"; 12 | "无法使用您的邮箱" = "无法使用您的邮箱"; 13 | "请在邮件应用中添加邮箱后再试" = "请在邮件应用中添加邮箱后再试"; 14 | 15 | //主界面 16 | "请输入套餐流量(单位MB)" = "请输入套餐流量(单位MB)"; 17 | "校准用量" = "校准用量"; 18 | "请输入已使用流量(单位MB)" = "请输入已使用流量(单位MB)"; 19 | "修改套餐" = "修改套餐"; 20 | 21 | //Alert 22 | "取消" = "取消"; 23 | "确定" = "确定"; 24 | "完成" = "完成"; 25 | 26 | //Detail 27 | "月" = "月"; 28 | "日" = "日"; -------------------------------------------------------------------------------- /NetAsistant/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 29 | 39 | 49 | 73 | 97 | 107 | 125 | 135 | 151 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 246 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 346 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Controllers/.DS_Store -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAAboutViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AboutViewController.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 11/29/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAAboutViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAAboutViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AboutViewController.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 11/29/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAAboutViewController.h" 10 | #import 11 | 12 | @interface SAAboutViewController () 13 | 14 | @property (weak, nonatomic) IBOutlet UILabel *versionLabel; 15 | 16 | @end 17 | 18 | @implementation SAAboutViewController 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; 24 | NSString *versionStr = [NSString stringWithFormat:@"%@ Build %@", [info objectForKey:@"CFBundleShortVersionString"], [info objectForKey:@"CFBundleVersion"]]; 25 | self.versionLabel.text = versionStr; 26 | } 27 | 28 | - (void)viewWillAppear:(BOOL)animated 29 | { 30 | [super viewWillAppear:animated]; 31 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault; 32 | [self.navigationController setNavigationBarHidden:NO animated:YES]; 33 | } 34 | 35 | - (void)viewWillDisappear:(BOOL)animated 36 | { 37 | [self.navigationController setNavigationBarHidden:YES animated:YES]; 38 | } 39 | 40 | - (void)didReceiveMemoryWarning 41 | { 42 | [super didReceiveMemoryWarning]; 43 | } 44 | 45 | #pragma mark - UITableViewDelegate 46 | 47 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 48 | { 49 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 50 | if (indexPath.section == 0) { 51 | if (indexPath.row == 0) { 52 | 53 | NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; 54 | NSString *versionStr = [NSString stringWithFormat:@"%@ Build %@", [info objectForKey:@"CFBundleShortVersionString"], [info objectForKey:@"CFBundleVersion"]]; 55 | NSString *message = [[NSString alloc] initWithFormat:NSLocalizedString(@"设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容", nil), [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion], versionStr]; 56 | __weak id target = self; 57 | MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init]; 58 | mailViewController.mailComposeDelegate = target; 59 | [mailViewController setToRecipients:@[@"netassistant@simpleapples.com"]]; 60 | [mailViewController setSubject:NSLocalizedString(@"用户反馈", nil)]; 61 | [mailViewController setMessageBody:message isHTML:NO]; 62 | if (![MFMailComposeViewController canSendMail]) { 63 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"无法使用您的邮箱", nil) message:NSLocalizedString(@"请在邮件应用中添加邮箱后再试", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"取消", nil) otherButtonTitles:NSLocalizedString(@"确定", nil), nil]; 64 | [alertView show]; 65 | } else { 66 | [self presentViewController:mailViewController animated:YES completion:nil]; 67 | } 68 | } else if (indexPath.row == 1) { 69 | NSString *urlStr = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=922017358"; 70 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlStr]]; 71 | } 72 | } 73 | } 74 | 75 | - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error 76 | { 77 | [controller dismissViewControllerAnimated:YES completion:nil]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SADetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADetailViewController.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SADetailViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SADetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADetailViewController.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADetailViewController.h" 10 | #import "SADetailCell.h" 11 | #import "SADetail.h" 12 | #import "SACoreDataManager.h" 13 | 14 | @interface SADetailViewController () 15 | 16 | @property (strong, nonatomic) NSArray *details; 17 | @property (nonatomic, getter = isCellRegistered) BOOL cellRegistered; 18 | 19 | @end 20 | 21 | @implementation SADetailViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | 27 | self.tableView.tableFooterView = [[UITableViewHeaderFooterView alloc] init]; 28 | 29 | [[SACoreDataManager manager] detailsOfThisMonth:^(NSArray *details) { 30 | if (details) { 31 | self.details = details; 32 | [self.tableView reloadData]; 33 | } 34 | }]; 35 | } 36 | 37 | - (void)viewWillAppear:(BOOL)animated 38 | { 39 | [super viewWillAppear:animated]; 40 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault; 41 | [self.navigationController setNavigationBarHidden:NO animated:YES]; 42 | } 43 | 44 | - (void)viewWillDisappear:(BOOL)animated 45 | { 46 | [self.navigationController setNavigationBarHidden:YES animated:YES]; 47 | } 48 | 49 | - (void)didReceiveMemoryWarning 50 | { 51 | [super didReceiveMemoryWarning]; 52 | } 53 | 54 | #pragma mark - UITableViewDelegate 55 | 56 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 57 | { 58 | static NSString *cellIdentifier = @"SADetailCell"; 59 | if (indexPath.row < self.details.count) { 60 | SADetail *detail = [self.details objectAtIndex:indexPath.row]; 61 | SADetailCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 62 | [cell configWithDetail:detail]; 63 | return cell; 64 | } 65 | return nil; 66 | } 67 | 68 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 69 | { 70 | return self.details.count; 71 | } 72 | 73 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 74 | { 75 | return 44; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InfoViewController.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 10/16/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "VVBlurViewController.h" 11 | 12 | @interface SAInfoViewController : VVBlurViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAInfoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InfoViewController.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 10/16/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAInfoViewController.h" 10 | 11 | @implementation SAInfoViewController 12 | 13 | - (void)viewDidLoad 14 | { 15 | [super viewDidLoad]; 16 | } 17 | 18 | - (void)viewWillAppear:(BOOL)animated 19 | { 20 | [super viewWillAppear:animated]; 21 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 22 | } 23 | 24 | - (void)didReceiveMemoryWarning 25 | { 26 | [super didReceiveMemoryWarning]; 27 | } 28 | 29 | - (IBAction)onCloseButtonClick:(id)sender 30 | { 31 | [self dismissViewControllerAnimated:YES completion:nil]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAMainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAMainViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /NetAsistant/Controllers/SAMainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAMainViewController.h" 10 | #import "SANetworkFlowService.h" 11 | #import "SANetworkFlow.h" 12 | #import "SAGlobalHolder.h" 13 | #import "SAConvertUtils.h" 14 | #import "SADateUtils.h" 15 | 16 | @interface SAMainViewController () 17 | 18 | @property (weak, nonatomic) IBOutlet UILabel *flowPercentLabel; 19 | @property (weak, nonatomic) IBOutlet UILabel *wwanFlowLabel; 20 | @property (weak, nonatomic) IBOutlet UILabel *limitFlowLabel; 21 | @property (weak, nonatomic) IBOutlet UIButton *calibrateButton; 22 | @property (weak, nonatomic) IBOutlet UIButton *modifyButton; 23 | 24 | @end 25 | 26 | @implementation SAMainViewController 27 | 28 | - (void)viewDidLoad 29 | { 30 | [super viewDidLoad]; 31 | 32 | self.calibrateButton.layer.borderColor = [[UIColor whiteColor] CGColor]; 33 | self.modifyButton.layer.borderColor = [[UIColor whiteColor] CGColor]; 34 | } 35 | 36 | - (void)viewWillAppear:(BOOL)animated 37 | { 38 | [super viewWillAppear:animated]; 39 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 40 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 41 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 42 | NSDate *nowDate = [NSDate date]; 43 | NSDate *lastDate = holder.lastRecordDate; 44 | if (holder.packageFlow <= 0) { 45 | [self alertModifyView]; 46 | } else if ([SADateUtils monthWithDate:nowDate] != [SADateUtils monthWithDate:lastDate] 47 | && [nowDate timeIntervalSince1970] > [lastDate timeIntervalSince1970]) { 48 | [holder cleanFlowOfLastMonth]; 49 | } 50 | [self updateFlowData]; 51 | }); 52 | } 53 | 54 | - (void)didReceiveMemoryWarning 55 | { 56 | [super didReceiveMemoryWarning]; 57 | } 58 | 59 | - (void)updateFlowData 60 | { 61 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 62 | SANetworkFlow *networkFlow = [SANetworkFlowService networkFlow]; 63 | if (networkFlow) { 64 | dispatch_async(dispatch_get_main_queue(), ^{ 65 | [[SAGlobalHolder sharedSingleton] updateDataWithNetworkFlow:networkFlow]; 66 | [self updateInterface]; 67 | }); 68 | } 69 | }); 70 | } 71 | 72 | - (void)updateInterface 73 | { 74 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 75 | if (holder.remainedFlow > 0) { 76 | NSInteger percent = holder.remainedFlow * 100.0f / holder.packageFlow; 77 | self.flowPercentLabel.text = [NSString stringWithFormat:@"%ld", (long)percent]; 78 | self.view.backgroundColor = [holder colorWithPercent:percent]; 79 | } else { 80 | self.flowPercentLabel.text = @"0"; 81 | self.view.backgroundColor = [holder colorWithType:COLOR_TYPE_ERROR]; 82 | } 83 | if (holder.packageFlow > 0) { 84 | self.limitFlowLabel.text = [SAConvertUtils bytesToString:holder.packageFlow]; 85 | } 86 | self.wwanFlowLabel.text = [SAConvertUtils bytesToString:holder.usedFlow]; 87 | } 88 | 89 | #pragma mark - UIAlertView 90 | 91 | - (void)alertModifyView 92 | { 93 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 94 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"修改套餐", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"取消", nil) otherButtonTitles:NSLocalizedString(@"完成", nil), nil]; 95 | alertView.alertViewStyle = UIAlertViewStylePlainTextInput; 96 | alertView.tag = 2; 97 | [alertView textFieldAtIndex:0].keyboardType = UIKeyboardTypeNumberPad; 98 | [alertView textFieldAtIndex:0].placeholder = NSLocalizedString(@"请输入套餐流量(单位MB)", nil); 99 | dispatch_async(dispatch_get_main_queue(), ^{ 100 | [alertView show]; 101 | }); 102 | }); 103 | } 104 | 105 | - (void)alertCalibrateView 106 | { 107 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 108 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"校准用量", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"取消", nil) otherButtonTitles:NSLocalizedString(@"完成", nil), nil]; 109 | alertView.alertViewStyle = UIAlertViewStylePlainTextInput; 110 | alertView.tag = 1; 111 | [alertView textFieldAtIndex:0].keyboardType = UIKeyboardTypeNumberPad; 112 | [alertView textFieldAtIndex:0].placeholder = NSLocalizedString(@"请输入已使用流量(单位MB)", nil); 113 | dispatch_async(dispatch_get_main_queue(), ^{ 114 | [alertView show]; 115 | }); 116 | }); 117 | } 118 | 119 | #pragma mark - UIAlertViewDelegate 120 | 121 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 122 | { 123 | if (buttonIndex == 1 && [alertView textFieldAtIndex:0].text.length > 0) { 124 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 125 | if (alertView.tag == 1) { 126 | int64_t usedFlow = [[alertView textFieldAtIndex:0].text floatValue] * 1000 * 1000; 127 | [holder calibrateUsedFlow:usedFlow]; 128 | } else if (alertView.tag == 2) { 129 | int64_t packageFlow = [[alertView textFieldAtIndex:0].text floatValue] * 1000 * 1000; 130 | [holder updatePackageFlow:packageFlow]; 131 | } 132 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 133 | [self updateFlowData]; 134 | }); 135 | } 136 | } 137 | 138 | #pragma mark - Handler 139 | 140 | - (IBAction)onCalibrateButtonClick:(id)sender 141 | { 142 | [self alertCalibrateView]; 143 | } 144 | 145 | - (IBAction)onModifyButtonClick:(id)sender 146 | { 147 | [self alertModifyView]; 148 | } 149 | 150 | @end 151 | -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "up&down1 3.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "iphone", 31 | "size" : "60x60", 32 | "scale" : "3x" 33 | } 34 | ], 35 | "info" : { 36 | "version" : 1, 37 | "author" : "xcode" 38 | } 39 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/AppIcon.appiconset/up&down1 3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/AppIcon.appiconset/up&down1 3.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "logo copy.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Icon.imageset/logo copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/Icon.imageset/logo copy.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconClose.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "IconClose.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconClose.imageset/IconClose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/IconClose.imageset/IconClose.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconInfo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "IconInfo.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconInfo.imageset/IconInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/IconInfo.imageset/IconInfo.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconMore.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "IconMore.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/IconMore.imageset/IconMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/IconMore.imageset/IconMore.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Step_1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "step1.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Step_1.imageset/step1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/Step_1.imageset/step1.png -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Step_2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "step2.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /NetAsistant/Images.xcassets/Step_2.imageset/step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Images.xcassets/Step_2.imageset/step2.png -------------------------------------------------------------------------------- /NetAsistant/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /NetAsistant/Libs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Libs/.DS_Store -------------------------------------------------------------------------------- /NetAsistant/Libs/Umeng/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Libs/Umeng/.DS_Store -------------------------------------------------------------------------------- /NetAsistant/Libs/Umeng/MobClick.h: -------------------------------------------------------------------------------- 1 | // 2 | // MobClick.h 3 | // Analytics 4 | // 5 | // Copyright (C) 2010-2015 Umeng.com . All rights reserved. 6 | 7 | #import 8 | #import 9 | 10 | #define UMOnlineConfigDidFinishedNotification @"OnlineConfigDidFinishedNotification" 11 | #define XcodeAppVersion [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] 12 | 13 | /** 14 | REALTIME只在模拟器和DEBUG模式下生效,真机的release模式会自动改成BATCH。 15 | */ 16 | typedef enum { 17 | REALTIME = 0, //实时发送 (只在测试模式下有效) 18 | BATCH = 1, //启动发送 19 | SEND_INTERVAL = 6, //最小间隔发送 ([90-86400]s, default 90s) 20 | 21 | // deprecated strategy: 22 | SENDDAILY = 4, //每日发送 (not available) 23 | SENDWIFIONLY = 5, //仅在WIFI下时启动发送 (not available) 24 | SEND_ON_EXIT = 7 //进入后台时发送 (not avilable, will be support later) 25 | } ReportPolicy; 26 | 27 | @class CLLocation; 28 | 29 | 30 | @interface MobClick : NSObject 31 | 32 | #pragma mark basics 33 | 34 | ///--------------------------------------------------------------------------------------- 35 | /// @name 设置 36 | ///--------------------------------------------------------------------------------------- 37 | 38 | /** 设置app版本号。由于历史原因需要和xcode3工程兼容,友盟提取的是Build号(CFBundleVersion), 39 | 如果需要和App Store上的版本一致,请调用此方法。 40 | @param appVersion 版本号,例如设置成`XcodeAppVersion`. 41 | @return void. 42 | */ 43 | + (void)setAppVersion:(NSString *)appVersion; 44 | 45 | /** 开启CrashReport收集, 默认YES(开启状态). 46 | @param value 设置为NO,可关闭友盟CrashReport收集功能. 47 | @return void. 48 | */ 49 | + (void)setCrashReportEnabled:(BOOL)value; 50 | 51 | /** 设置是否打印sdk的log信息, 默认NO(不打印log). 52 | @param value 设置为YES,umeng SDK 会输出log信息可供调试参考. 除非特殊需要,否则发布产品时需改回NO. 53 | @return void. 54 | */ 55 | + (void)setLogEnabled:(BOOL)value; 56 | 57 | /** 设置是否开启background模式, 默认YES. 58 | @param value 为YES,SDK会确保在app进入后台的短暂时间保存日志信息的完整性,对于已支持background模式和一般app不会有影响. 59 | 如果该模式影响某些App在切换到后台的功能,也可将该值设置为NO. 60 | @return void. 61 | */ 62 | + (void)setBackgroundTaskEnabled:(BOOL)value; 63 | 64 | /** 设置是否对日志信息进行加密, 默认NO(不加密). 65 | @param value 设置为YES, umeng SDK 会将日志信息做加密处理 66 | @return void. 67 | */ 68 | + (void)setEncryptEnabled:(BOOL)value; 69 | 70 | ///--------------------------------------------------------------------------------------- 71 | /// @name 开启统计 72 | ///--------------------------------------------------------------------------------------- 73 | 74 | /** 初始化友盟统计模块 75 | @param appKey 友盟appKey. 76 | @return void 77 | */ 78 | + (void)startWithAppkey:(NSString *)appKey; 79 | 80 | /** 初始化友盟统计模块 81 | @param appKey 友盟appKey. 82 | @param reportPolicy 发送策略, 默认值为:BATCH,即“启动发送”模式 83 | @param channelId 渠道名称,为nil或@""时, 默认为@"App Store"渠道 84 | @return void 85 | */ 86 | + (void)startWithAppkey:(NSString *)appKey reportPolicy:(ReportPolicy)rp channelId:(NSString *)cid; 87 | 88 | /** 当reportPolicy == SEND_INTERVAL 时设定log发送间隔 89 | @param second 单位为秒,最小90秒,最大86400秒(24hour). 90 | @return void. 91 | */ 92 | + (void)setLogSendInterval:(double)second; 93 | 94 | /** 设置日志延迟发送 95 | @param second 设置一个[0, second]范围的延迟发送秒数,最大值1800s. 96 | @return void 97 | */ 98 | + (void)setLatency:(int)second; 99 | 100 | ///--------------------------------------------------------------------------------------- 101 | /// @name 页面计时 102 | ///--------------------------------------------------------------------------------------- 103 | 104 | /** 手动页面时长统计, 记录某个页面展示的时长. 105 | @param pageName 统计的页面名称. 106 | @param seconds 单位为秒,int型. 107 | @return void. 108 | */ 109 | + (void)logPageView:(NSString *)pageName seconds:(int)seconds; 110 | 111 | /** 自动页面时长统计, 开始记录某个页面展示时长. 112 | 使用方法:必须配对调用beginLogPageView:和endLogPageView:两个函数来完成自动统计,若只调用某一个函数不会生成有效数据。 113 | 在该页面展示时调用beginLogPageView:,当退出该页面时调用endLogPageView: 114 | @param pageName 统计的页面名称. 115 | @return void. 116 | */ 117 | + (void)beginLogPageView:(NSString *)pageName; 118 | 119 | /** 自动页面时长统计, 结束记录某个页面展示时长. 120 | 使用方法:必须配对调用beginLogPageView:和endLogPageView:两个函数来完成自动统计,若只调用某一个函数不会生成有效数据。 121 | 在该页面展示时调用beginLogPageView:,当退出该页面时调用endLogPageView: 122 | @param pageName 统计的页面名称. 123 | @return void. 124 | */ 125 | + (void)endLogPageView:(NSString *)pageName; 126 | 127 | #pragma mark event logs 128 | 129 | ///--------------------------------------------------------------------------------------- 130 | /// @name 事件统计 131 | ///--------------------------------------------------------------------------------------- 132 | 133 | /** 自定义事件,数量统计. 134 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID 135 | 136 | @param eventId 网站上注册的事件Id. 137 | @param label 分类标签。不同的标签会分别进行统计,方便同一事件的不同标签的对比,为nil或空字符串时后台会生成和eventId同名的标签. 138 | @param accumulation 累加值。为减少网络交互,可以自行对某一事件ID的某一分类标签进行累加,再传入次数作为参数。 139 | @return void. 140 | */ 141 | + (void)event:(NSString *)eventId; //等同于 event:eventId label:eventId; 142 | /** 自定义事件,数量统计. 143 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID 144 | */ 145 | + (void)event:(NSString *)eventId label:(NSString *)label; // label为nil或@""时,等同于 event:eventId label:eventId; 146 | 147 | /** 自定义事件,数量统计. 148 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID 149 | */ 150 | + (void)event:(NSString *)eventId attributes:(NSDictionary *)attributes; 151 | 152 | + (void)event:(NSString *)eventId attributes:(NSDictionary *)attributes counter:(int)number; 153 | 154 | /** 自定义事件,时长统计. 155 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 156 | beginEvent,endEvent要配对使用,也可以自己计时后通过durations参数传递进来 157 | 158 | @param eventId 网站上注册的事件Id. 159 | @param label 分类标签。不同的标签会分别进行统计,方便同一事件的不同标签的对比,为nil或空字符串时后台会生成和eventId同名的标签. 160 | @param primarykey 这个参数用于和event_id一起标示一个唯一事件,并不会被统计;对于同一个事件在beginEvent和endEvent 中要传递相同的eventId 和 primarykey 161 | @param millisecond 自己计时需要的话需要传毫秒进来 162 | @return void. 163 | 164 | 165 | @warning 每个event的attributes不能超过10个 166 | eventId、attributes中key和value都不能使用空格和特殊字符,且长度不能超过255个字符(否则将截取前255个字符) 167 | id, ts, du是保留字段,不能作为eventId及key的名称 168 | 169 | */ 170 | + (void)beginEvent:(NSString *)eventId; 171 | /** 自定义事件,时长统计. 172 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 173 | */ 174 | + (void)endEvent:(NSString *)eventId; 175 | /** 自定义事件,时长统计. 176 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 177 | */ 178 | 179 | + (void)beginEvent:(NSString *)eventId label:(NSString *)label; 180 | /** 自定义事件,时长统计. 181 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 182 | */ 183 | 184 | + (void)endEvent:(NSString *)eventId label:(NSString *)label; 185 | /** 自定义事件,时长统计. 186 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 187 | */ 188 | 189 | + (void)beginEvent:(NSString *)eventId primarykey :(NSString *)keyName attributes:(NSDictionary *)attributes; 190 | /** 自定义事件,时长统计. 191 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 192 | */ 193 | 194 | + (void)endEvent:(NSString *)eventId primarykey:(NSString *)keyName; 195 | /** 自定义事件,时长统计. 196 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 197 | */ 198 | 199 | + (void)event:(NSString *)eventId durations:(int)millisecond; 200 | /** 自定义事件,时长统计. 201 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 202 | */ 203 | 204 | + (void)event:(NSString *)eventId label:(NSString *)label durations:(int)millisecond; 205 | /** 自定义事件,时长统计. 206 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID. 207 | */ 208 | + (void)event:(NSString *)eventId attributes:(NSDictionary *)attributes durations:(int)millisecond; 209 | 210 | 211 | #pragma mark AutoUpdate and Online Configure 212 | ///--------------------------------------------------------------------------------------- 213 | /// @name 按渠道自动更新 214 | ///--------------------------------------------------------------------------------------- 215 | 216 | /** 按渠道检测更新 217 | 检查当前app是否有更新,有则弹出UIAlertView提示用户,当用户点击升级按钮时app会跳转到您预先设置的网址。 218 | 无更新不做任何操作。 219 | 需要先在服务器端设置app版本信息,默认渠道是App Store. 220 | @return void. 221 | */ 222 | + (void)checkUpdate; 223 | 224 | /** 按渠道检测更新 225 | 检查当前app是否有更新,有则弹出UIAlertView提示用户,当用户点击升级按钮时app会跳转到您预先设置的网址。 226 | 无更新不做任何操作。 227 | 需要先在服务器端设置app版本信息,默认渠道是App Store. 228 | 229 | @param title 对应UIAlertView的title. 230 | @param cancelTitle 对应UIAlertView的cancelTitle. 231 | @param otherTitle 对应UIAlertView的otherTitle. 232 | @return void. 233 | */ 234 | + (void)checkUpdate:(NSString *)title cancelButtonTitle:(NSString *)cancelTitle otherButtonTitles:(NSString *)otherTitle; 235 | 236 | /** 设置自由控制更新callback函数 237 | 若程序需要自由控制收到更新内容后的流程可设置delegate和callback函数来完成 238 | 239 | @param delegate 需要自定义checkUpdate的对象. 240 | @param callBackSelectorWithDictionary 当checkUpdate事件完成时此方法会被调用,同时标记app更新信息的字典被传回. 241 | */ 242 | + (void)checkUpdateWithDelegate:(id)delegate selector:(SEL)callBackSelectorWithDictionary; 243 | 244 | 245 | ///--------------------------------------------------------------------------------------- 246 | /// @name 在线参数:可以动态设定应用中的参数值 247 | ///--------------------------------------------------------------------------------------- 248 | 249 | /** 此方法会检查并下载服务端设置的在线参数,例如可在线更改SDK端发送策略。 250 | 请在[MobClick startWithAppkey:]方法之后调用; 251 | 监听在线参数更新是否完成,可注册UMOnlineConfigDidFinishedNotification通知 252 | @param . 253 | @return void. 254 | */ 255 | + (void)updateOnlineConfig; 256 | 257 | /** 返回已缓存的在线参数值 258 | 带参数的方法获取某个key的值,不带参数的获取所有的在线参数. 259 | 需要先调用updateOnlineConfig才能使用,如果想知道在线参数是否完成完成,请监听UMOnlineConfigDidFinishedNotification 260 | @param key 261 | @return (NSString *) . 262 | */ 263 | + (NSString *)getConfigParams:(NSString *)key; 264 | + (NSDictionary *)getConfigParams; 265 | + (NSString *)getAdURL; 266 | 267 | ///--------------------------------------------------------------------------------------- 268 | /// @name 地理位置设置 269 | /// 需要链接 CoreLocation.framework 并且 #import 270 | ///--------------------------------------------------------------------------------------- 271 | 272 | /** 设置经纬度信息 273 | @param latitude 纬度. 274 | @param longitude 经度. 275 | @return void 276 | */ 277 | + (void)setLatitude:(double)latitude longitude:(double)longitude; 278 | 279 | /** 设置经纬度信息 280 | @param location CLLocation 经纬度信息 281 | @return void 282 | */ 283 | + (void)setLocation:(CLLocation *)location; 284 | 285 | 286 | ///--------------------------------------------------------------------------------------- 287 | /// @name Utility函数 288 | ///--------------------------------------------------------------------------------------- 289 | 290 | /** 判断设备是否越狱,依据是否存在apt和Cydia.app 291 | */ 292 | + (BOOL)isJailbroken; 293 | 294 | /** 判断App是否被破解 295 | */ 296 | + (BOOL)isPirated; 297 | 298 | #pragma mark DEPRECATED 299 | 300 | + (void)event:(NSString *)eventId acc:(NSInteger)accumulation; 301 | /** 自定义事件,数量统计. 302 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID 303 | */ 304 | + (void)event:(NSString *)eventId label:(NSString *)label acc:(NSInteger)accumulation; 305 | /** 自定义事件,数量统计. 306 | 使用前,请先到友盟App管理后台的设置->编辑自定义事件 中添加相应的事件ID,然后在工程中传入相应的事件ID 307 | */ 308 | 309 | /** 友盟模块启动 310 | [MobClick startWithAppkey:]通常在application:didFinishLaunchingWithOptions:里被调用监听App启动和退出事件, 311 | 如果开发者无法在此处添加友盟的[MobClick startWithAppkey:]方法,App的启动事件可能会无法监听,此时需要手动调用[MobClick startSession:nil]来启动友盟的session。 312 | 上述情况通常发生在某些第三方框架生成的app里,普通app不用关注该API. 313 | */ 314 | + (void)startSession:(NSNotification *)notification; 315 | 316 | @end 317 | -------------------------------------------------------------------------------- /NetAsistant/Libs/Umeng/libMobClickLibrary.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Libs/Umeng/libMobClickLibrary.a -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurPresentationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurPresentationController.h 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @interface VVBlurPresentationController : UIPresentationController 27 | 28 | @property (nonatomic, assign) UIBlurEffectStyle blurStyle; 29 | 30 | - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController style:(UIBlurEffectStyle)style; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurPresentationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurPresentationController.m 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "VVBlurPresentationController.h" 25 | 26 | @interface VVBlurPresentationController () 27 | //We need an effect container view to suppress the annoying warning on alpha of a visual effect view. 28 | @property (nonatomic, strong) UIView *effectContainerView; 29 | @property (nonatomic, strong) UIVisualEffectView *dimmingView; 30 | @end 31 | 32 | @implementation VVBlurPresentationController 33 | 34 | - (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController style:(UIBlurEffectStyle)style { 35 | self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController]; 36 | if (self) { 37 | UIBlurEffect *effect = [UIBlurEffect effectWithStyle:style]; 38 | _dimmingView = [[UIVisualEffectView alloc] initWithEffect:effect]; 39 | _blurStyle = style; 40 | _effectContainerView = [UIView new]; 41 | _effectContainerView.alpha = 0.0; 42 | } 43 | return self; 44 | } 45 | 46 | - (void)presentationTransitionWillBegin { 47 | self.effectContainerView.frame = self.containerView.bounds; 48 | self.dimmingView.frame = self.containerView.bounds; 49 | 50 | [self.effectContainerView insertSubview:self.dimmingView atIndex:0]; 51 | [self.containerView insertSubview:self.effectContainerView atIndex:0]; 52 | 53 | self.effectContainerView.alpha = 0.0; 54 | 55 | id coordinator = [self.presentedViewController transitionCoordinator]; 56 | if (coordinator) { 57 | [coordinator animateAlongsideTransition:^(id context) { 58 | self.effectContainerView.alpha = 1.0; 59 | } completion:nil]; 60 | } else { 61 | self.effectContainerView.alpha = 1.0; 62 | } 63 | } 64 | 65 | - (void)dismissalTransitionWillBegin { 66 | id coordinator = [self.presentedViewController transitionCoordinator]; 67 | if (coordinator) { 68 | [coordinator animateAlongsideTransition:^(id context) { 69 | self.effectContainerView.alpha = 0.0; 70 | } completion:nil]; 71 | } else { 72 | self.effectContainerView.alpha = 0.0; 73 | } 74 | } 75 | 76 | - (void)containerViewWillLayoutSubviews { 77 | self.effectContainerView.frame = self.containerView.bounds; 78 | self.dimmingView.frame = self.containerView.bounds; 79 | self.presentedView.frame = self.containerView.bounds; 80 | } 81 | 82 | - (BOOL)shouldPresentInFullscreen { 83 | return YES; 84 | } 85 | 86 | - (UIModalPresentationStyle)adaptivePresentationStyle { 87 | return UIModalPresentationCustom; 88 | } 89 | 90 | - (void)setBlurStyle:(UIBlurEffectStyle)blurStyle { 91 | if (blurStyle != _blurStyle) { 92 | _blurStyle = blurStyle; 93 | 94 | UIView *previousDimmingView = _dimmingView; 95 | 96 | UIBlurEffect *effect = [UIBlurEffect effectWithStyle:blurStyle]; 97 | self.dimmingView = [[UIVisualEffectView alloc] initWithEffect:effect]; 98 | NSArray *subviews = [self.effectContainerView subviews]; 99 | for (UIView *view in subviews) { 100 | if (view == previousDimmingView) { 101 | self.dimmingView.frame = previousDimmingView.frame; 102 | [self.effectContainerView insertSubview:self.dimmingView aboveSubview:previousDimmingView]; 103 | [previousDimmingView removeFromSuperview]; 104 | } 105 | } 106 | } 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurPresenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurPresenter.h 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @interface VVBlurPresenter : NSObject 27 | @property (nonatomic, assign) UIBlurEffectStyle blurStyle; 28 | @end 29 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurPresenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurPresenter.m 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "VVBlurPresenter.h" 25 | #import "VVBlurPresentationController.h" 26 | #import "VVBlurTransitioning.h" 27 | 28 | @interface VVBlurPresenter () 29 | @property (nonatomic, strong) VVBlurPresentationController *animationController; 30 | @end 31 | 32 | @implementation VVBlurPresenter 33 | 34 | - (instancetype)init { 35 | self = [super init]; 36 | if (self) { 37 | _blurStyle = UIBlurEffectStyleDark; 38 | } 39 | return self; 40 | } 41 | 42 | - (VVBlurPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented 43 | presentingViewController:(UIViewController *)presenting 44 | sourceViewController:(UIViewController *)source { 45 | if (!self.animationController) { 46 | self.animationController = [[VVBlurPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting style:self.blurStyle]; 47 | } 48 | return self.animationController; 49 | 50 | } 51 | 52 | - (id)animationControllerForPresentedController:(UIViewController *)presented 53 | presentingController:(UIViewController *)presenting 54 | sourceController:(UIViewController *)source { 55 | 56 | VVBlurTransitioning *transition = [VVBlurTransitioning new]; 57 | transition.isPresentation = YES; 58 | return transition; 59 | 60 | } 61 | 62 | - (id)animationControllerForDismissedController:(UIViewController *)dismissed { 63 | 64 | VVBlurTransitioning *transition = [VVBlurTransitioning new]; 65 | transition.isPresentation = NO; 66 | return transition; 67 | } 68 | 69 | - (void)setBlurStyle:(UIBlurEffectStyle)blurStyle { 70 | if (_blurStyle != blurStyle) { 71 | _blurStyle = blurStyle; 72 | self.animationController.blurStyle = blurStyle; 73 | } 74 | } 75 | @end 76 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurTransitioning.h: -------------------------------------------------------------------------------- 1 | // 2 | // VVChromeTransitioner.h 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @interface VVBlurTransitioning : NSObject 27 | @property (nonatomic, assign) BOOL isPresentation; 28 | @end 29 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurTransitioning.m: -------------------------------------------------------------------------------- 1 | // 2 | // VVChromeTransitioner.m 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "VVBlurTransitioning.h" 25 | 26 | @implementation VVBlurTransitioning 27 | 28 | -(NSTimeInterval)transitionDuration:(id)transitionContext { 29 | return 0.5; 30 | } 31 | 32 | -(void)animateTransition:(id)transitionContext { 33 | UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 34 | UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 35 | 36 | UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; 37 | UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; 38 | 39 | UIView *containerView = [transitionContext containerView]; 40 | if (self.isPresentation) { 41 | [containerView addSubview:toView]; 42 | } 43 | 44 | UIViewController *animatingViewController = self.isPresentation ? toViewController : fromViewController; 45 | UIView *animatingView = self.isPresentation ? toView : fromView; 46 | 47 | CGRect onScreenFrame = [transitionContext finalFrameForViewController:animatingViewController]; 48 | CGRect offScreenFrame = CGRectOffset(onScreenFrame, 0, onScreenFrame.size.height); 49 | 50 | CGRect initialFrame = self.isPresentation ? offScreenFrame : onScreenFrame; 51 | CGRect finalFrame = self.isPresentation ? onScreenFrame : offScreenFrame; 52 | animatingView.frame = initialFrame; 53 | 54 | [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 usingSpringWithDamping:300.0 initialSpringVelocity:5.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{ 55 | animatingView.frame = finalFrame; 56 | } completion:^(BOOL finished) { 57 | if (!self.isPresentation) { 58 | [fromView removeFromSuperview]; 59 | } 60 | [transitionContext completeTransition:YES]; 61 | }]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurViewController.h 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @interface VVBlurViewController : UIViewController 27 | @property (nonatomic, assign) UIBlurEffectStyle blurStyle; 28 | @end 29 | -------------------------------------------------------------------------------- /NetAsistant/Libs/VVBlurPresentation/VVBlurViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // VVBlurViewController.m 3 | // 4 | // Copyright (c) 2015 Wei Wang (http://onevcat.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "VVBlurViewController.h" 25 | #import "VVBlurPresenter.h" 26 | 27 | @interface VVBlurViewController () 28 | @property (nonatomic, strong) VVBlurPresenter *presenter; 29 | @end 30 | 31 | @implementation VVBlurViewController 32 | 33 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 34 | self = [super initWithCoder:aDecoder]; 35 | if (self) { 36 | [self vv_commonSetup]; 37 | } 38 | return self; 39 | } 40 | 41 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 42 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 43 | if (self) { 44 | [self vv_commonSetup]; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)vv_commonSetup { 50 | self.modalPresentationStyle = UIModalPresentationCustom; 51 | 52 | _presenter = [[VVBlurPresenter alloc] init]; 53 | _blurStyle = UIBlurEffectStyleDark; 54 | _presenter.blurStyle = _blurStyle; 55 | 56 | self.transitioningDelegate = _presenter; 57 | } 58 | 59 | - (void)viewDidLoad { 60 | [super viewDidLoad]; 61 | self.view.backgroundColor = [UIColor clearColor]; 62 | } 63 | 64 | -(void)setBlurStyle:(UIBlurEffectStyle)blurStyle { 65 | if (blurStyle != _blurStyle) { 66 | _blurStyle = blurStyle; 67 | _presenter.blurStyle = blurStyle; 68 | } 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /NetAsistant/Models/SADetail.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADetail.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface SADetail : NSManagedObject 14 | 15 | @property (nonatomic, retain) NSNumber * flowValue; 16 | @property (nonatomic, retain) NSDate * date; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /NetAsistant/Models/SADetail.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADetail.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADetail.h" 10 | 11 | 12 | @implementation SADetail 13 | 14 | @dynamic flowValue; 15 | @dynamic date; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /NetAsistant/Models/SANetworkFlow.h: -------------------------------------------------------------------------------- 1 | // 2 | // SANetworkFlow.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SANetworkFlow : NSObject 13 | 14 | @property (nonatomic, readonly) int64_t allFlow; 15 | @property (nonatomic, readonly) int64_t allInFlow; 16 | @property (nonatomic, readonly) int64_t allOutFlow; 17 | @property (nonatomic, readonly) int64_t wifiFlow; 18 | @property (nonatomic, readonly) int64_t wifiInFlow; 19 | @property (nonatomic, readonly) int64_t wifiOutFlow; 20 | @property (nonatomic, readonly) int64_t wwanFlow; 21 | @property (nonatomic, readonly) int64_t wwanInFlow; 22 | @property (nonatomic, readonly) int64_t wwanOutFlow; 23 | 24 | - (instancetype)initWithAllFlow:(int64_t)allFlow allInFlow:(int64_t)allInFlow allOutFlow:(int64_t)allOutFlow wifiFlow:(int64_t)wifiFlow wifiInFlow:(int64_t)wifiInFlow wifiOutFlow:(int64_t)wifiOutFlow wwanFlow:(int64_t)wwanFlow wwanInFlow:(int64_t)wwanInFlow wwanOutFlow:(int64_t)wwanOutFlow; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /NetAsistant/Models/SANetworkFlow.m: -------------------------------------------------------------------------------- 1 | // 2 | // SANetworkFlow.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SANetworkFlow.h" 10 | 11 | @interface SANetworkFlow () 12 | 13 | @property (nonatomic) int64_t allFlow; 14 | @property (nonatomic) int64_t allInFlow; 15 | @property (nonatomic) int64_t allOutFlow; 16 | @property (nonatomic) int64_t wifiFlow; 17 | @property (nonatomic) int64_t wifiInFlow; 18 | @property (nonatomic) int64_t wifiOutFlow; 19 | @property (nonatomic) int64_t wwanFlow; 20 | @property (nonatomic) int64_t wwanInFlow; 21 | @property (nonatomic) int64_t wwanOutFlow; 22 | 23 | @end 24 | 25 | @implementation SANetworkFlow 26 | 27 | - (instancetype)init 28 | { 29 | @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must use initWithAllFlow:allInFlow:allOutFlow:wifiFlow:wifiInFlow:wifiOutFlow:wwanFlow:wwanInFlow:wwanOutFlow: instead." userInfo:nil]; 30 | } 31 | 32 | - (instancetype)initWithAllFlow:(int64_t)allFlow allInFlow:(int64_t)allInFlow allOutFlow:(int64_t)allOutFlow wifiFlow:(int64_t)wifiFlow wifiInFlow:(int64_t)wifiInFlow wifiOutFlow:(int64_t)wifiOutFlow wwanFlow:(int64_t)wwanFlow wwanInFlow:(int64_t)wwanInFlow wwanOutFlow:(int64_t)wwanOutFlow 33 | { 34 | self = [super init]; 35 | if (self) { 36 | self.allFlow = allFlow; 37 | self.allInFlow = allInFlow; 38 | self.allOutFlow = allOutFlow; 39 | self.wifiFlow = wifiFlow; 40 | self.wifiInFlow = wifiInFlow; 41 | self.wifiOutFlow = wifiOutFlow; 42 | self.wwanFlow = wwanFlow; 43 | self.wwanInFlow = wwanInFlow; 44 | self.wwanOutFlow = wwanOutFlow; 45 | } 46 | return self; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /NetAsistant/NetAsistant.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.netasistant 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /NetAsistant/Services/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/NetAsistant/Services/.DS_Store -------------------------------------------------------------------------------- /NetAsistant/Services/SACoreDataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SACoreDataManager.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 12/24/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SADetail.h" 11 | 12 | @class SADetail; 13 | 14 | @interface SACoreDataManager : NSObject 15 | 16 | + (SACoreDataManager *)manager; 17 | 18 | - (void)insertOrUpdateDetailWithFlowValue:(int64_t)flowValue date:(NSDate *)date; 19 | - (void)detailsOfThisMonth:(void(^)(NSArray *details))completionBlock; 20 | 21 | - (void)saveContext; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /NetAsistant/Services/SACoreDataManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SACoreDataManager.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 12/24/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SACoreDataManager.h" 10 | #import "SADateUtils.h" 11 | #import 12 | 13 | @interface SACoreDataManager () 14 | 15 | @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; 16 | @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; 17 | @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 18 | 19 | @end 20 | 21 | @implementation SACoreDataManager 22 | 23 | + (SACoreDataManager *)manager 24 | { 25 | static SACoreDataManager *manager; 26 | static dispatch_once_t token = 0; 27 | dispatch_once(&token, ^{ 28 | if (!manager) { 29 | manager = [[SACoreDataManager alloc] init]; 30 | } 31 | }); 32 | return manager; 33 | } 34 | 35 | #pragma mark - SADetail 36 | 37 | - (void)insertOrUpdateDetailWithFlowValue:(int64_t)flowValue date:(NSDate *)date 38 | { 39 | NSInteger year = [SADateUtils yearWithDate:date]; 40 | NSInteger month = [SADateUtils monthWithDate:date]; 41 | NSInteger day = [SADateUtils dayWithDate:date]; 42 | NSDate *dayDate = [SADateUtils dayDateWithStirng:[NSString stringWithFormat:@"%ld-%ld-%ld 00:00:00", (long)year, (long)month, (long)day]]; 43 | 44 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"SADetail"]; 45 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"date = %@", dayDate]; 46 | fetchRequest.fetchLimit = 1; 47 | 48 | NSError *error; 49 | NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 50 | if (!error && fetchResult && fetchResult.count) { 51 | SADetail *existDetail = [fetchResult firstObject]; 52 | existDetail.flowValue = @(existDetail.flowValue.longLongValue + flowValue); 53 | } else { 54 | SADetail *detail = [NSEntityDescription insertNewObjectForEntityForName:@"SADetail" inManagedObjectContext:self.managedObjectContext]; 55 | detail.flowValue = @(flowValue); 56 | detail.date = dayDate; 57 | } 58 | } 59 | 60 | - (void)detailsOfThisMonth:(void(^)(NSArray *details))completionBlock 61 | { 62 | NSParameterAssert(completionBlock); 63 | 64 | NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]; 65 | NSArray *sortArray = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 66 | 67 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"SADetail"]; 68 | fetchRequest.fetchLimit = 365; 69 | fetchRequest.sortDescriptors = sortArray; 70 | 71 | NSAsynchronousFetchRequest *asyncFetchRequest = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest:fetchRequest completionBlock:^(NSAsynchronousFetchResult *result) { 72 | if (result && result.finalResult && result.finalResult.count) { 73 | dispatch_async(dispatch_get_main_queue(), ^{ 74 | completionBlock(result.finalResult); 75 | }); 76 | } else { 77 | dispatch_async(dispatch_get_main_queue(), ^{ 78 | completionBlock(nil); 79 | }); 80 | } 81 | }]; 82 | NSError *error; 83 | [self.managedObjectContext executeRequest:asyncFetchRequest error:&error]; 84 | if (error) { 85 | completionBlock(nil); 86 | } 87 | } 88 | 89 | #pragma mark - Core Data stack 90 | 91 | - (NSURL *)applicationDocumentsDirectory 92 | { 93 | return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 94 | } 95 | 96 | - (NSManagedObjectModel *)managedObjectModel 97 | { 98 | if (_managedObjectModel != nil) { 99 | return _managedObjectModel; 100 | } 101 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"netasistant" withExtension:@"momd"]; 102 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 103 | return _managedObjectModel; 104 | } 105 | 106 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator 107 | { 108 | if (_persistentStoreCoordinator != nil) { 109 | return _persistentStoreCoordinator; 110 | } 111 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 112 | NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"netasistant.sqlite"]; 113 | NSError *error = nil; 114 | NSString *failureReason = @"There was an error creating or loading the application's saved data."; 115 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 116 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 117 | dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; 118 | dict[NSLocalizedFailureReasonErrorKey] = failureReason; 119 | dict[NSUnderlyingErrorKey] = error; 120 | error = [NSError errorWithDomain:@"com.zangzhiya.netasistant" code:1000 userInfo:dict]; 121 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 122 | abort(); 123 | } 124 | return _persistentStoreCoordinator; 125 | } 126 | 127 | - (NSManagedObjectContext *)managedObjectContext 128 | { 129 | if (_managedObjectContext != nil) { 130 | return _managedObjectContext; 131 | } 132 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 133 | if (!coordinator) { 134 | return nil; 135 | } 136 | _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 137 | [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 138 | return _managedObjectContext; 139 | } 140 | 141 | #pragma mark - Core Data Saving support 142 | 143 | - (void)saveContext 144 | { 145 | NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 146 | if (managedObjectContext != nil) { 147 | NSError *error = nil; 148 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 149 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 150 | abort(); 151 | } 152 | } 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /NetAsistant/Services/SAGlobalHolder.h: -------------------------------------------------------------------------------- 1 | // 2 | // GlobalHolder.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_OPTIONS(NSInteger, COLOR_TYPE) 13 | { 14 | COLOR_TYPE_NORMAL = 0, 15 | COLOR_TYPE_WARNNING, 16 | COLOR_TYPE_ERROR, 17 | }; 18 | 19 | @class SANetworkFlow; 20 | 21 | @interface SAGlobalHolder : NSObject 22 | 23 | @property (nonatomic, readonly) int64_t packageFlow; 24 | @property (nonatomic, readonly) int64_t usedFlow; 25 | @property (nonatomic, readonly) int64_t remainedFlow; 26 | @property (nonatomic, readonly) int64_t lastRecordFlow; 27 | @property (strong, nonatomic, readonly) NSDate *lastRecordDate; 28 | 29 | + (SAGlobalHolder *)sharedSingleton; 30 | 31 | - (void)updateDataWithNetworkFlow:(SANetworkFlow *)networkFlow; 32 | - (void)updatePackageFlow:(int64_t)packageFlow; 33 | - (void)calibrateUsedFlow:(int64_t)usedFlow; 34 | - (void)cleanFlowOfLastMonth; 35 | 36 | - (UIColor *)colorWithType:(COLOR_TYPE)type; 37 | - (UIColor *)colorWithPercent:(NSInteger)percent; 38 | 39 | - (void)backupToFile; 40 | - (void)recoverFromFile; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /NetAsistant/Services/SAGlobalHolder.m: -------------------------------------------------------------------------------- 1 | // 2 | // GlobalHolder.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAGlobalHolder.h" 10 | #import "SANetworkFlow.h" 11 | #import "SACoreDataManager.h" 12 | #import "SAConvertUtils.h" 13 | 14 | @interface SAGlobalHolder () 15 | 16 | @property (nonatomic, readwrite) int64_t packageFlow; 17 | @property (nonatomic, readwrite) int64_t usedFlow; 18 | @property (nonatomic, readwrite) int64_t remainedFlow; 19 | @property (nonatomic, readwrite) int64_t lastRecordFlow; 20 | @property (strong, nonatomic, readwrite) NSDate *lastRecordDate; 21 | @property (strong, nonatomic) NSArray *colorArray; 22 | 23 | @end 24 | 25 | @implementation SAGlobalHolder 26 | 27 | + (SAGlobalHolder *)sharedSingleton 28 | { 29 | static SAGlobalHolder *sharedSingleton; 30 | static dispatch_once_t onceToken = 0; 31 | dispatch_once(&onceToken, ^{ 32 | if (!sharedSingleton) { 33 | sharedSingleton = [[SAGlobalHolder alloc] init]; 34 | } 35 | }); 36 | return sharedSingleton; 37 | } 38 | 39 | - (instancetype)init 40 | { 41 | self = [super init]; 42 | if (self) { 43 | UIColor *yellow = [UIColor colorWithRed:252 / 255.0f green:176 / 255.0f blue:60 / 255.0f alpha:1.0f]; 44 | UIColor *red = [UIColor colorWithRed:252 / 255.0f green:91 / 255.0f blue:63 / 255.0f alpha:1.0f]; 45 | UIColor *green = [UIColor colorWithRed:79 / 255.0f green:202 / 255.0f blue:82 / 255.0f alpha:1.0f]; 46 | self.colorArray = [[NSArray alloc] initWithObjects:green, yellow, red, nil]; 47 | [self recoverFromFile]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)updateDataWithNetworkFlow:(SANetworkFlow *)networkFlow 53 | { 54 | int64_t increasedFlow = 0; 55 | if (networkFlow.wwanFlow >= self.lastRecordFlow) { 56 | increasedFlow = networkFlow.wwanFlow - self.lastRecordFlow; 57 | self.usedFlow = increasedFlow + self.usedFlow; 58 | } 59 | NSDate *nowDate = [NSDate date]; 60 | [[SACoreDataManager manager] insertOrUpdateDetailWithFlowValue:increasedFlow date:nowDate]; 61 | self.remainedFlow = self.packageFlow - self.usedFlow; 62 | self.lastRecordFlow = networkFlow.wwanFlow; 63 | self.lastRecordDate = nowDate; 64 | } 65 | 66 | - (void)updatePackageFlow:(int64_t)packageFlow 67 | { 68 | self.packageFlow = packageFlow; 69 | } 70 | 71 | - (void)calibrateUsedFlow:(int64_t)usedFlow 72 | { 73 | self.usedFlow = usedFlow; 74 | self.lastRecordDate = [NSDate date]; 75 | } 76 | 77 | - (void)cleanFlowOfLastMonth 78 | { 79 | self.usedFlow = 0; 80 | self.lastRecordDate = [NSDate date]; 81 | } 82 | 83 | #pragma mark - Color 84 | 85 | - (UIColor *)colorWithType:(COLOR_TYPE)type 86 | { 87 | switch (type) { 88 | case COLOR_TYPE_NORMAL: 89 | return [self.colorArray objectAtIndex:0]; 90 | case COLOR_TYPE_WARNNING: 91 | return [self.colorArray objectAtIndex:1]; 92 | case COLOR_TYPE_ERROR: 93 | return [self.colorArray objectAtIndex:2]; 94 | } 95 | } 96 | 97 | - (UIColor *)colorWithPercent:(NSInteger)percent 98 | { 99 | if (percent < 10) { 100 | return [self colorWithType:COLOR_TYPE_ERROR]; 101 | } else if (percent < 20) { 102 | return [self colorWithType:COLOR_TYPE_WARNNING]; 103 | } 104 | return [self colorWithType:COLOR_TYPE_NORMAL]; 105 | } 106 | 107 | #pragma mark - UserDefaults 108 | 109 | - (void)backupToFile 110 | { 111 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.netasistant"]; 112 | [userDefaults setObject:[NSNumber numberWithLongLong:self.packageFlow] forKey:@"limitFlow"]; 113 | [userDefaults setObject:[NSNumber numberWithLongLong:self.usedFlow] forKey:@"offsetFlow"]; 114 | [userDefaults setObject:[NSNumber numberWithLongLong:self.remainedFlow] forKey:@"remainedFlow"]; 115 | [userDefaults setObject:[NSNumber numberWithLongLong:self.lastRecordFlow] forKey:@"lastFlow"]; 116 | [userDefaults setObject:self.lastRecordDate forKey:@"lastDate"]; 117 | [userDefaults synchronize]; 118 | } 119 | 120 | - (void)recoverFromFile 121 | { 122 | NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.netasistant"]; 123 | self.packageFlow = [[userDefaults objectForKey:@"limitFlow"] longLongValue]; 124 | self.usedFlow = [[userDefaults objectForKey:@"offsetFlow"] longLongValue]; 125 | self.remainedFlow = [[userDefaults objectForKey:@"remainedFlow"] longLongValue]; 126 | self.lastRecordFlow = [[userDefaults objectForKey:@"lastFlow"] longLongValue]; 127 | self.lastRecordDate = [userDefaults objectForKey:@"lastDate"]; 128 | } 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /NetAsistant/Services/SANetworkFlowService.h: -------------------------------------------------------------------------------- 1 | // 2 | // SANetworkFlowService.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SANetworkFlow; 12 | @interface SANetworkFlowService : NSObject 13 | 14 | + (SANetworkFlow *)networkFlow; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /NetAsistant/Services/SANetworkFlowService.m: -------------------------------------------------------------------------------- 1 | // 2 | // SANetworkFlowService.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SANetworkFlowService.h" 10 | #import "SANetworkFlow.h" 11 | #include 12 | #include 13 | #include 14 | 15 | @implementation SANetworkFlowService 16 | 17 | + (SANetworkFlow *)networkFlow 18 | { 19 | struct ifaddrs *ifa_list = 0, *ifa; 20 | if (getifaddrs(&ifa_list) == -1) { 21 | return nil; 22 | } 23 | 24 | int64_t iBytes = 0; 25 | int64_t oBytes = 0; 26 | int64_t allFlow = 0; 27 | int64_t wifiIBytes = 0; 28 | int64_t wifiOBytes = 0; 29 | int64_t wifiFlow = 0; 30 | int64_t wwanIBytes = 0; 31 | int64_t wwanOBytes = 0; 32 | int64_t wwanFlow = 0; 33 | 34 | for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) { 35 | if (AF_LINK != ifa->ifa_addr->sa_family) { 36 | continue; 37 | } 38 | if (!(ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_RUNNING)) { 39 | continue; 40 | } 41 | if (ifa->ifa_data == 0) { 42 | continue; 43 | } 44 | if (strncmp(ifa->ifa_name, "lo", 2)) { 45 | struct if_data *if_data = (struct if_data *)ifa->ifa_data; 46 | iBytes += if_data->ifi_ibytes; 47 | oBytes += if_data->ifi_obytes; 48 | allFlow = iBytes + oBytes; 49 | } 50 | if (!strcmp(ifa->ifa_name, "en0")) { 51 | struct if_data *if_data = (struct if_data *)ifa->ifa_data; 52 | wifiIBytes += if_data->ifi_ibytes; 53 | wifiOBytes += if_data->ifi_obytes; 54 | wifiFlow = wifiIBytes + wifiOBytes; 55 | } 56 | if (!strcmp(ifa->ifa_name, "pdp_ip0")) { 57 | struct if_data *if_data = (struct if_data *)ifa->ifa_data; 58 | wwanIBytes += if_data->ifi_ibytes; 59 | wwanOBytes += if_data->ifi_obytes; 60 | wwanFlow = wwanIBytes + wwanOBytes; 61 | } 62 | } 63 | freeifaddrs(ifa_list); 64 | 65 | SANetworkFlow *networkFlow = [[SANetworkFlow alloc] initWithAllFlow:allFlow allInFlow:iBytes allOutFlow:oBytes wifiFlow:wifiIBytes wifiInFlow:wifiIBytes wifiOutFlow:wifiOBytes wwanFlow:wwanFlow wwanInFlow:wwanIBytes wwanOutFlow:wwanOBytes]; 66 | return networkFlow; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /NetAsistant/Utils/SAConvertUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConvertUtils.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAConvertUtils : NSObject 12 | 13 | + (NSString *)bytesToString:(int64_t)bytes; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /NetAsistant/Utils/SAConvertUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAConvertUtils.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAConvertUtils.h" 10 | 11 | @implementation SAConvertUtils 12 | 13 | + (NSString *)bytesToString:(int64_t)bytes 14 | { 15 | if (bytes < 1000) { 16 | return [NSString stringWithFormat:@"%lluB", bytes]; 17 | } else if (bytes >= 1000 && bytes < 1000 * 1000) { 18 | return [NSString stringWithFormat:@"%.1fKB", 1.0 * bytes / 1000]; 19 | } else if (bytes >= 1000 * 1000 && bytes < 1000 * 1000 * 1000) { 20 | return [NSString stringWithFormat:@"%.2fMB", 1.0 * bytes / (1000 * 1000)]; 21 | } 22 | return [NSString stringWithFormat:@"%.2fGB", 1.0 * bytes / (1000 * 1000 * 1000)]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /NetAsistant/Utils/SADateUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADateUtils.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SADateUtils : NSObject 12 | 13 | + (NSInteger)yearWithDate:(NSDate *)date; 14 | + (NSInteger)monthWithDate:(NSDate *)date; 15 | + (NSInteger)dayWithDate:(NSDate *)date; 16 | 17 | + (NSString *)stringWithDate:(NSDate *)date; 18 | + (NSDate *)dayDateWithStirng:(NSString *)string; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /NetAsistant/Utils/SADateUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADateUtils.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADateUtils.h" 10 | 11 | @implementation SADateUtils 12 | 13 | static NSDateFormatter *dateFormatter; 14 | 15 | + (void)initialize 16 | { 17 | if (!dateFormatter) { 18 | dateFormatter = [[NSDateFormatter alloc] init]; 19 | dateFormatter.timeZone = [NSTimeZone localTimeZone]; 20 | } 21 | } 22 | 23 | + (NSInteger)yearWithDate:(NSDate *)date 24 | { 25 | [dateFormatter setDateFormat:@"YYYY"]; 26 | return [dateFormatter stringFromDate:date].integerValue; 27 | } 28 | 29 | + (NSInteger)monthWithDate:(NSDate *)date 30 | { 31 | [dateFormatter setDateFormat:@"M"]; 32 | return [dateFormatter stringFromDate:date].integerValue; 33 | } 34 | 35 | + (NSInteger)dayWithDate:(NSDate *)date 36 | { 37 | [dateFormatter setDateFormat:@"d"]; 38 | return [dateFormatter stringFromDate:date].integerValue; 39 | } 40 | 41 | + (NSString *)stringWithDate:(NSDate *)date 42 | { 43 | [dateFormatter setDateFormat:[NSString stringWithFormat:@"M%@d%@", NSLocalizedString(@"月", nil), NSLocalizedString(@"日", nil)]]; 44 | return [dateFormatter stringFromDate:date]; 45 | } 46 | 47 | + (NSDate *)dayDateWithStirng:(NSString *)string 48 | { 49 | [dateFormatter setDateFormat:@"YYYY-M-d HH:mm:ss"]; 50 | return [dateFormatter dateFromString:string]; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /NetAsistant/Views/SADetailCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADetailCell.h 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SADetail; 12 | 13 | @interface SADetailCell : UITableViewCell 14 | 15 | - (void)configWithDetail:(SADetail *)detail; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /NetAsistant/Views/SADetailCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADetailCell.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 3/7/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADetailCell.h" 10 | #import "SADateUtils.h" 11 | #import "SADetail.h" 12 | #import "SAConvertUtils.h" 13 | 14 | @interface SADetailCell () 15 | 16 | @property (weak, nonatomic) IBOutlet UILabel *dateLabel; 17 | @property (weak, nonatomic) IBOutlet UILabel *flowLabel; 18 | 19 | @end 20 | 21 | @implementation SADetailCell 22 | 23 | - (void)awakeFromNib 24 | { 25 | } 26 | 27 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 28 | { 29 | [super setSelected:selected animated:animated]; 30 | } 31 | 32 | - (void)configWithDetail:(SADetail *)detail 33 | { 34 | self.dateLabel.text = [SADateUtils stringWithDate:detail.date]; 35 | self.flowLabel.text = [SAConvertUtils bytesToString:detail.flowValue.longLongValue]; 36 | } 37 | 38 | - (void)prepareForReuse 39 | { 40 | self.dateLabel.text = @""; 41 | self.flowLabel.text = @""; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /NetAsistant/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "NetAssistant"; 10 | "CFBundleName" = "NetAssistant"; -------------------------------------------------------------------------------- /NetAsistant/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localization.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | //邮件反馈 10 | "设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容" = "Device: %@ %@, Software Version: %@ \n\nPlease input your feedback:"; 11 | "用户反馈" = "Feedback"; 12 | "无法使用您的邮箱" = "Mail Unavailable"; 13 | "请在邮件应用中添加邮箱后再试" = "Please add a mailbox"; 14 | 15 | //主界面 16 | "请输入套餐流量(单位MB)" = "Input Package (MB)"; 17 | "校准用量" = "Standard Package"; 18 | "请输入已使用流量(单位MB)" = "Standard Package (MB)"; 19 | "修改套餐" = "Upgrade Package"; 20 | 21 | //Alert 22 | "取消" = "Cancel"; 23 | "确定" = "Confirm"; 24 | "完成" = "Done"; 25 | 26 | //Detail 27 | "月" = "-"; 28 | "日" = ""; -------------------------------------------------------------------------------- /NetAsistant/en.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | /* Class = "IBUILabel"; text = "剩余"; ObjectID = "2C6-cQ-HkJ"; */ 2 | "2C6-cQ-HkJ.text" = "Left"; 3 | 4 | /* Class = "IBUILabel"; text = "第一步:下滑打开通知栏,点击「编辑」"; ObjectID = "4H4-Eb-5jK"; */ 5 | "4H4-Eb-5jK.text" = "Step 1:下滑打开通知栏,点击「编辑」"; 6 | 7 | /* Class = "IBUIButton"; normalTitle = "校准用量"; ObjectID = "5Xv-Vf-7ba"; */ 8 | "5Xv-Vf-7ba.normalTitle" = "Standard"; 9 | 10 | /* Class = "IBUIButton"; normalTitle = "修改套餐"; ObjectID = "CmJ-E3-dwk"; */ 11 | "CmJ-E3-dwk.normalTitle" = "Upgrade"; 12 | 13 | /* Class = "IBUIViewController"; title = "InfoViewController"; ObjectID = "Ev1-gI-f1H"; */ 14 | "Ev1-gI-f1H.title" = "InfoViewController"; 15 | 16 | /* Class = "IBUINavigationItem"; title = "详单"; ObjectID = "K9S-Rn-VY4"; */ 17 | "K9S-Rn-VY4.title" = "Detail"; 18 | 19 | /* Class = "IBUILabel"; text = "反馈问题"; ObjectID = "OzG-9S-gka"; */ 20 | "OzG-9S-gka.text" = "Feedback"; 21 | 22 | /* Class = "IBUILabel"; text = "版本"; ObjectID = "Qcn-Ri-mw1"; */ 23 | "Qcn-Ri-mw1.text" = "Version"; 24 | 25 | /* Class = "IBUILabel"; text = "%"; ObjectID = "Scd-f7-iU3"; */ 26 | "Scd-f7-iU3.text" = "%"; 27 | 28 | /* Class = "IBUIButton"; normalTitle = " Widget使用指南"; ObjectID = "YC9-Zc-Mx7"; */ 29 | "YC9-Zc-Mx7.normalTitle" = " Widget Guide"; 30 | 31 | /* Class = "IBUITableViewSection"; headerTitle = "反馈"; ObjectID = "ZJp-k8-RoC"; */ 32 | "ZJp-k8-RoC.headerTitle" = "Feedback"; 33 | 34 | /* Class = "IBUILabel"; text = "90"; ObjectID = "dCa-nA-6Fx"; */ 35 | "dCa-nA-6Fx.text" = "90"; 36 | 37 | /* Class = "IBUILabel"; text = "1.0 "; ObjectID = "eV2-Ai-dat"; */ 38 | "eV2-Ai-dat.text" = "1.0 "; 39 | 40 | /* Class = "IBUIButton"; normalTitle = "详单"; ObjectID = "fSr-gh-Kf3"; */ 41 | "fSr-gh-Kf3.normalTitle" = "Detail"; 42 | 43 | /* Class = "IBUILabel"; text = "0B"; ObjectID = "fnS-vR-4Bd"; */ 44 | "fnS-vR-4Bd.text" = "0B"; 45 | 46 | /* Class = "IBUITableViewSection"; headerTitle = "关于"; ObjectID = "o6S-2e-nZs"; */ 47 | "o6S-2e-nZs.headerTitle" = "About"; 48 | 49 | /* Class = "IBUILabel"; text = "0B"; ObjectID = "pwf-6A-GaQ"; */ 50 | "pwf-6A-GaQ.text" = "0B"; 51 | 52 | /* Class = "IBUINavigationItem"; title = "关于"; ObjectID = "qYS-aU-Icd"; */ 53 | "qYS-aU-Icd.title" = "About"; 54 | 55 | /* Class = "IBUILabel"; text = "第二步:点击「上网助手」前的加号,完成后点击右上角「完成」"; ObjectID = "slc-Cg-ta9"; */ 56 | "slc-Cg-ta9.text" = "Step 2:点击「上网助手」前的加号,完成后点击右上角「完成」"; 57 | 58 | /* Class = "IBUILabel"; text = "为上网助手评分"; ObjectID = "tjd-7g-1yA"; */ 59 | "tjd-7g-1yA.text" = "Rate"; 60 | 61 | /* Class = "IBUIViewController"; title = "MainViewController"; ObjectID = "vXZ-lx-hvc"; */ 62 | "vXZ-lx-hvc.title" = "MainViewController"; 63 | 64 | /* Class = "IBUITableViewController"; title = "AboutViewController"; ObjectID = "zhd-fp-Gh5"; */ 65 | "zhd-fp-Gh5.title" = "AboutViewController"; 66 | 67 | 68 | -------------------------------------------------------------------------------- /NetAsistant/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NetAsistant 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /NetAsistant/netasistant.xcdatamodeld/netasistant.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /NetAsistant/zh-Hans.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* 2 | InfoPlist.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | "CFBundleDisplayName" = "上网助手"; 10 | "CFBundleName" = "上网助手"; -------------------------------------------------------------------------------- /NetAsistant/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | Localization.strings 3 | NetAsistant 4 | 5 | Created by Zzy on 1/6/15. 6 | Copyright (c) 2015 Zzy. All rights reserved. 7 | */ 8 | 9 | //邮件反馈 10 | "设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容" = "设备: %@ %@, 软件版本: %@ \n\n请在这里填写您的反馈内容"; 11 | "用户反馈" = "用户反馈"; 12 | "无法使用您的邮箱" = "无法使用您的邮箱"; 13 | "请在邮件应用中添加邮箱后再试" = "请在邮件应用中添加邮箱后再试"; 14 | 15 | //主界面 16 | "请输入套餐流量(单位MB)" = "请输入套餐流量(单位MB)"; 17 | "校准用量" = "校准用量"; 18 | "请输入已使用流量(单位MB)" = "请输入已使用流量(单位MB)"; 19 | "修改套餐" = "修改套餐"; 20 | 21 | //Alert 22 | "取消" = "取消"; 23 | "确定" = "确定"; 24 | "完成" = "完成"; 25 | 26 | //Detail 27 | "月" = "月"; 28 | "日" = "日"; -------------------------------------------------------------------------------- /NetAsistant/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "IBUILabel"; text = "剩余"; ObjectID = "2C6-cQ-HkJ"; */ 3 | "2C6-cQ-HkJ.text" = "剩余"; 4 | 5 | /* Class = "IBUIButton"; normalTitle = "校准用量"; ObjectID = "5Xv-Vf-7ba"; */ 6 | "5Xv-Vf-7ba.normalTitle" = "校准用量"; 7 | 8 | /* Class = "IBUIButton"; normalTitle = "修改套餐"; ObjectID = "CmJ-E3-dwk"; */ 9 | "CmJ-E3-dwk.normalTitle" = "修改套餐"; 10 | 11 | /* Class = "IBUILabel"; text = "%"; ObjectID = "Scd-f7-iU3"; */ 12 | "Scd-f7-iU3.text" = "%"; 13 | 14 | /* Class = "IBUILabel"; text = "0"; ObjectID = "dCa-nA-6Fx"; */ 15 | "dCa-nA-6Fx.text" = "0"; 16 | 17 | /* Class = "IBUILabel"; text = "0B"; ObjectID = "fnS-vR-4Bd"; */ 18 | "fnS-vR-4Bd.text" = "0B"; 19 | 20 | /* Class = "IBUILabel"; text = "0B"; ObjectID = "pwf-6A-GaQ"; */ 21 | "pwf-6A-GaQ.text" = "0B"; 22 | -------------------------------------------------------------------------------- /NetAsistantTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.zangzhiya.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /NetAsistantTests/NetAsistantTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // NetAsistantTests.m 3 | // NetAsistantTests 4 | // 5 | // Created by Zzy on 9/20/14. 6 | // Copyright (c) 2014 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface NetAsistantTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation NetAsistantTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NetAsistant 2 | =========== 3 | 4 | 上网助手 - 在通知中心查看流量使用情况 5 | 6 | 7 | 8 | ## 截屏 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## 构建 17 | 18 | 上网助手使用[Cocoapods](https://github.com/CocoaPods/CocoaPods)构建 19 | 20 | ## 许可证 21 | 22 | This code is distributed under the terms and conditions of the MIT license. 23 | 24 | ``` 25 | Copyright (C) 2015 Zhiya Zang 26 | 27 | Permission is hereby granted, free of charge, to any person obtaining a copy of 28 | this software and associated documentation files (the "Software"), to deal in 29 | the Software without restriction, including without limitation the rights to 30 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 31 | the Software, and to permit persons to whom the Software is furnished to do so, 32 | subject to the following conditions: 33 | 34 | The above copyright notice and this permission notice shall be included in all 35 | copies or substantial portions of the Software. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 39 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 40 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 41 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 42 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43 | ``` 44 | -------------------------------------------------------------------------------- /上网助手 WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/29@3x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/29@3x-1.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/29@3x.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/net-assistant/1b9241ab112df59ceb6fe3c9cb9a64cfabcd279e/上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /上网助手 WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "filename" : "48.png", 8 | "role" : "notificationCenter", 9 | "subtype" : "38mm" 10 | }, 11 | { 12 | "size" : "27.5x27.5", 13 | "idiom" : "watch", 14 | "scale" : "2x", 15 | "filename" : "55.png", 16 | "role" : "notificationCenter", 17 | "subtype" : "42mm" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "watch", 22 | "filename" : "29@3x-1.png", 23 | "role" : "companionSettings", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "size" : "29x29", 28 | "idiom" : "watch", 29 | "filename" : "29@3x.png", 30 | "role" : "companionSettings", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "watch", 36 | "scale" : "2x", 37 | "filename" : "80.png", 38 | "role" : "appLauncher", 39 | "subtype" : "38mm" 40 | }, 41 | { 42 | "size" : "44x44", 43 | "idiom" : "watch", 44 | "scale" : "2x", 45 | "filename" : "88.png", 46 | "role" : "longLook", 47 | "subtype" : "42mm" 48 | }, 49 | { 50 | "size" : "86x86", 51 | "idiom" : "watch", 52 | "scale" : "2x", 53 | "filename" : "172.png", 54 | "role" : "quickLook", 55 | "subtype" : "38mm" 56 | }, 57 | { 58 | "size" : "98x98", 59 | "idiom" : "watch", 60 | "scale" : "2x", 61 | "filename" : "196.png", 62 | "role" : "quickLook", 63 | "subtype" : "42mm" 64 | } 65 | ], 66 | "info" : { 67 | "version" : 1, 68 | "author" : "xcode" 69 | } 70 | } -------------------------------------------------------------------------------- /上网助手 WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 上网助手 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.zangzhiya.netasistant.watchkitapp 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.7 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 51 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | com.zangzhiya.netasistant 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/GlanceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GlanceController.h 3 | // 上网助手 WatchKit Extension 4 | // 5 | // Created by Zzy on 6/2/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface GlanceController : WKInterfaceController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/GlanceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GlanceController.m 3 | // 上网助手 WatchKit Extension 4 | // 5 | // Created by Zzy on 6/2/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "GlanceController.h" 10 | #import "SAGlobalHolder.h" 11 | 12 | @interface GlanceController() 13 | 14 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *flowPercentLabel; 15 | 16 | @end 17 | 18 | 19 | @implementation GlanceController 20 | 21 | - (void)awakeWithContext:(id)context 22 | { 23 | [super awakeWithContext:context]; 24 | } 25 | 26 | - (void)willActivate 27 | { 28 | [super willActivate]; 29 | 30 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 31 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 32 | NSInteger percent = 0; 33 | if (holder.remainedFlow > 0) { 34 | percent = holder.remainedFlow * 100.0f / holder.packageFlow; 35 | } 36 | UIColor *color = [holder colorWithPercent:percent]; 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | self.flowPercentLabel.text = [NSString stringWithFormat:@"%zd%%", percent]; 39 | [self.flowPercentLabel setTextColor:color]; 40 | }); 41 | }); 42 | } 43 | 44 | - (void)didDeactivate 45 | { 46 | [super didDeactivate]; 47 | } 48 | 49 | @end 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 上网助手 WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.zangzhiya.netasistant.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.7 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 51 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | com.zangzhiya.netasistant.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/InterfaceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.h 3 | // 上网助手 WatchKit Extension 4 | // 5 | // Created by Zzy on 6/2/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface InterfaceController : WKInterfaceController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/InterfaceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.m 3 | // 上网助手 WatchKit Extension 4 | // 5 | // Created by Zzy on 6/2/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "InterfaceController.h" 10 | #import "SAGlobalHolder.h" 11 | #import "SAConvertUtils.h" 12 | 13 | @interface InterfaceController() 14 | 15 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *flowPercentLabel; 16 | @property (weak, nonatomic) IBOutlet WKInterfaceLabel *remainedFlowLabel; 17 | @property (weak, nonatomic) IBOutlet WKInterfaceGroup *remainedFlowGroup; 18 | 19 | @end 20 | 21 | 22 | @implementation InterfaceController 23 | 24 | - (void)awakeWithContext:(id)context 25 | { 26 | [super awakeWithContext:context]; 27 | } 28 | 29 | - (void)willActivate 30 | { 31 | [super willActivate]; 32 | 33 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 34 | SAGlobalHolder *holder = [SAGlobalHolder sharedSingleton]; 35 | NSInteger percent = 0; 36 | if (holder.remainedFlow > 0) { 37 | percent = holder.remainedFlow * 100.0f / holder.packageFlow; 38 | } 39 | UIColor *color = [holder colorWithPercent:percent]; 40 | dispatch_async(dispatch_get_main_queue(), ^{ 41 | self.flowPercentLabel.text = [NSString stringWithFormat:@"%zd%%", percent]; 42 | self.remainedFlowLabel.text = [NSString stringWithFormat:@"%@可用", [SAConvertUtils bytesToString:holder.remainedFlow]]; 43 | [self.remainedFlowGroup setBackgroundColor:color]; 44 | }); 45 | }); 46 | } 47 | 48 | - (void)didDeactivate 49 | { 50 | [super didDeactivate]; 51 | } 52 | 53 | @end 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /上网助手 WatchKit Extension/上网助手 WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.netasistant 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------