├── .gitignore ├── LICENSE ├── PHPHub.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── PHPHub.xcworkspace └── contents.xcworkspacedata ├── PHPHub ├── Apis │ ├── AdApi.h │ ├── AdApi.m │ ├── CategoryApi.h │ ├── CategoryApi.m │ ├── NotificationApi.h │ ├── NotificationApi.m │ ├── TopicApi.h │ ├── TopicApi.m │ ├── UserApi.h │ └── UserApi.m ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── BaseClasses │ ├── BaseApi.h │ ├── BaseApi.m │ ├── BaseDBManager.h │ ├── BaseDBManager.m │ ├── BaseEntity.h │ ├── BaseEntity.m │ ├── BaseModel.h │ ├── BaseModel.m │ ├── CurrentUser.h │ └── CurrentUser.m ├── Constants │ ├── APIConstant.h │ ├── DebugConstant.h │ ├── SecretConstant.example.h │ └── UIConstant.h ├── Controllers │ ├── Essential │ │ ├── EssentialListViewController.h │ │ └── EssentialListViewController.m │ ├── Forum │ │ ├── TopicListContainerViewController.h │ │ ├── TopicListContainerViewController.m │ │ ├── TopicListViewController.h │ │ └── TopicListViewController.m │ ├── Me │ │ ├── MeViewController.h │ │ └── MeViewController.m │ ├── Notification │ │ ├── NotificationListViewController.h │ │ └── NotificationListViewController.m │ ├── Passport │ │ ├── LoginViewController.h │ │ └── LoginViewController.m │ ├── Settings │ │ ├── SettingsViewController.h │ │ └── SettingsViewController.m │ ├── TabBar │ │ ├── BaseTabBarViewController.h │ │ └── BaseTabBarViewController.m │ ├── Topic │ │ ├── PostTopicViewController.h │ │ ├── PostTopicViewController.m │ │ ├── ReplyTopicViewController.h │ │ ├── ReplyTopicViewController.m │ │ ├── TopicDetailViewController.h │ │ └── TopicDetailViewController.m │ ├── User │ │ ├── EditUserProfileViewController.h │ │ ├── EditUserProfileViewController.m │ │ ├── UserProfileViewController.h │ │ └── UserProfileViewController.m │ └── WiKi │ │ ├── WiKiListViewController.h │ │ └── WiKiListViewController.m ├── Handlers │ ├── APIRequestHandler.h │ ├── APIRequestHandler.m │ ├── AccessTokenHandler.h │ ├── AccessTokenHandler.m │ ├── AnalyticsHandler.h │ ├── AnalyticsHandler.m │ ├── ExceptionHandler.h │ ├── ExceptionHandler.m │ ├── JpushHandler.h │ ├── JpushHandler.m │ ├── JumpToOtherVCHandler.h │ ├── JumpToOtherVCHandler.m │ ├── LaunchScreenAdHandler.h │ ├── LaunchScreenAdHandler.m │ ├── UMengSocialHandler.h │ └── UMengSocialHandler.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── 167.png │ │ ├── Contents.json │ │ ├── icon_100.png │ │ ├── icon_114.png │ │ ├── icon_120-1.png │ │ ├── icon_120.png │ │ ├── icon_144.png │ │ ├── icon_152.png │ │ ├── icon_180.png │ │ ├── icon_29-1.png │ │ ├── icon_29.png │ │ ├── icon_40.png │ │ ├── icon_50.png │ │ ├── icon_57.png │ │ ├── icon_58-1.png │ │ ├── icon_58.png │ │ ├── icon_72.png │ │ ├── icon_76.png │ │ ├── icon_80-1.png │ │ ├── icon_80.png │ │ └── icon_87.png │ ├── Base │ │ ├── Contents.json │ │ ├── back.imageset │ │ │ ├── Contents.json │ │ │ └── back.png │ │ ├── cancel.imageset │ │ │ ├── Contents.json │ │ │ └── cancel.png │ │ ├── estgroup_short_intro.imageset │ │ │ ├── Contents.json │ │ │ └── estgroup_short_intro.png │ │ ├── logo.imageset │ │ │ ├── Contents.json │ │ │ └── icon_180.png │ │ ├── more.imageset │ │ │ ├── Contents.json │ │ │ └── more_icon.png │ │ └── pure_icon.imageset │ │ │ ├── Contents.json │ │ │ └── pure_icon.png │ ├── Contents.json │ ├── Me │ │ ├── Contents.json │ │ ├── comment_icon.imageset │ │ │ ├── Contents.json │ │ │ └── comment_icon.png │ │ ├── favorite_icon.imageset │ │ │ ├── Contents.json │ │ │ └── favorite_icon.png │ │ ├── ring_icon.imageset │ │ │ ├── Contents.json │ │ │ └── ring_icon.png │ │ ├── settings_icon.imageset │ │ │ ├── Contents.json │ │ │ └── settings_icon.png │ │ ├── topic_icon.imageset │ │ │ ├── Contents.json │ │ │ └── topic_icon.png │ │ └── watch_icon.imageset │ │ │ ├── Contents.json │ │ │ └── watch_icon.png │ ├── Passport │ │ └── anonymous_logo.imageset │ │ │ ├── Contents.json │ │ │ └── anonymous_logo.png │ ├── TabBar │ │ ├── Contents.json │ │ ├── comments_icon.imageset │ │ │ ├── Contents.json │ │ │ └── comments_icon.png │ │ ├── essential_icon.imageset │ │ │ ├── Contents.json │ │ │ └── essential_icon.png │ │ ├── essential_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── essential_selected_icon.png │ │ ├── forum_icon.imageset │ │ │ ├── Contents.json │ │ │ └── forum_icon.png │ │ ├── forum_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── forum_selected_icon.png │ │ ├── me_icon.imageset │ │ │ ├── Contents.json │ │ │ └── me_icon.png │ │ ├── me_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── me_selected_icon.png │ │ ├── reply_icon.imageset │ │ │ ├── Contents.json │ │ │ └── reply_icon.png │ │ ├── tabbar_backgroud.imageset │ │ │ ├── Contents.json │ │ │ └── tabbar_background@2x.png │ │ ├── wiki_icon.imageset │ │ │ ├── Contents.json │ │ │ └── wiki_icon.png │ │ └── wiki_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── wiki_selected_icon.png │ ├── Topic │ │ ├── Contents.json │ │ ├── avatar_placeholder.imageset │ │ │ ├── Contents.json │ │ │ └── avatar_placeholder.png │ │ ├── big_downvote_icon.imageset │ │ │ ├── Contents.json │ │ │ └── big_downvote_icon.png │ │ ├── big_downvote_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── big_downvote__selected_icon.png │ │ ├── big_upvote_icon.imageset │ │ │ ├── Contents.json │ │ │ └── big_upvote_icon.png │ │ ├── big_upvote_selected_icon.imageset │ │ │ ├── Contents.json │ │ │ └── big_upvote_selected_icon.png │ │ ├── corner_circle.imageset │ │ │ ├── Contents.json │ │ │ └── corner_circle.png │ │ ├── downvote_icon.imageset │ │ │ ├── Contents.json │ │ │ └── downvote_icon.png │ │ ├── favorite_blue_icon.imageset │ │ │ ├── Contents.json │ │ │ └── favorite_blue_icon.png │ │ ├── link_icon.imageset │ │ │ ├── Contents.json │ │ │ └── link_icon.png │ │ ├── pencil_icon.imageset │ │ │ ├── Contents.json │ │ │ └── pencil_icon.png │ │ ├── pencil_square_icon.imageset │ │ │ ├── Contents.json │ │ │ └── pencil_square_icon.png │ │ ├── sad_face.imageset │ │ │ ├── Contents.json │ │ │ └── sad_face.png │ │ ├── send_icon.imageset │ │ │ ├── Contents.json │ │ │ └── send_icon.png │ │ ├── share_icon.imageset │ │ │ ├── Contents.json │ │ │ └── share_icon.png │ │ ├── upvote_icon.imageset │ │ │ ├── Contents.json │ │ │ └── upvote_icon.png │ │ ├── vote_icon.imageset │ │ │ ├── Contents.json │ │ │ └── vote_icon.png │ │ ├── voted_icon.imageset │ │ │ ├── Contents.json │ │ │ └── voted_icon.png │ │ └── watch_blue_icon.imageset │ │ │ ├── Contents.json │ │ │ └── watch_blue_icon.png │ ├── User │ │ ├── Contents.json │ │ ├── blog_icon.imageset │ │ │ ├── Contents.json │ │ │ └── blog_icon.png │ │ ├── edit_profile_icon.imageset │ │ │ ├── Contents.json │ │ │ └── edit_profile_icon.png │ │ ├── github_icon.imageset │ │ │ ├── Contents.json │ │ │ └── github_icon.png │ │ ├── local_icon.imageset │ │ │ ├── Contents.json │ │ │ └── local_icon.png │ │ ├── tick_icon.imageset │ │ │ ├── Contents.json │ │ │ └── tick_icon.png │ │ └── twitter_icon.imageset │ │ │ ├── Contents.json │ │ │ └── twitter_icon.png │ └── ViewPager │ │ └── pager_title_indicator.imageset │ │ ├── Contents.json │ │ └── pager_title_indicator.png ├── Info.plist ├── Models │ ├── AdModel.h │ ├── AdModel.m │ ├── CategoryModel.h │ ├── CategoryModel.m │ ├── NotificationModel.h │ ├── NotificationModel.m │ ├── TopicModel.h │ ├── TopicModel.m │ ├── UserModel.h │ └── UserModel.m ├── PHPHub-Prefix.pch ├── PushConfig.example.plist ├── Resources │ └── Migrations.bundle │ │ ├── 20151002095034729_create_users_table.sql │ │ └── 20151019093301120_create_launchScreenAds_table.sql ├── ThirdParty │ ├── GoogleAnalytics │ │ ├── Library │ │ │ ├── GAI.h │ │ │ ├── GAIDictionaryBuilder.h │ │ │ ├── GAIEcommerceFields.h │ │ │ ├── GAIEcommerceProduct.h │ │ │ ├── GAIEcommerceProductAction.h │ │ │ ├── GAIEcommercePromotion.h │ │ │ ├── GAIFields.h │ │ │ ├── GAILogger.h │ │ │ ├── GAITrackedViewController.h │ │ │ └── GAITracker.h │ │ └── libGoogleAnalyticsServices.a │ ├── JPush │ │ └── lib │ │ │ ├── APService.h │ │ │ └── libPushSDK-1.8.5.a │ ├── TOWebViewController │ │ ├── TOActivityChrome.h │ │ ├── TOActivityChrome.m │ │ ├── TOActivitySafari.h │ │ ├── TOActivitySafari.m │ │ ├── TOWebViewController.h │ │ ├── TOWebViewController.m │ │ ├── UIImage+TOWebViewControllerIcons.h │ │ └── UIImage+TOWebViewControllerIcons.m │ ├── TPKeyboardAvoiding │ │ ├── TPKeyboardAvoidingCollectionView.h │ │ ├── TPKeyboardAvoidingCollectionView.m │ │ ├── TPKeyboardAvoidingScrollView.h │ │ ├── TPKeyboardAvoidingScrollView.m │ │ ├── TPKeyboardAvoidingTableView.h │ │ ├── TPKeyboardAvoidingTableView.m │ │ ├── UIScrollView+TPKeyboardAvoidingAdditions.h │ │ └── UIScrollView+TPKeyboardAvoidingAdditions.m │ ├── TitlePagerView │ │ ├── TitlePagerView.h │ │ └── TitlePagerView.m │ ├── ViewPagerController │ │ ├── ViewPagerController.h │ │ └── ViewPagerController.m │ └── WCAlertView │ │ ├── WCAlertView.h │ │ └── WCAlertView.m ├── Utils │ ├── Categories │ │ ├── AFOAuth2Manager │ │ │ ├── AFOAuth2Manager+Addtions.h │ │ │ └── AFOAuth2Manager+Addtions.m │ │ ├── GVUserDefaults │ │ │ ├── GVUserDefaults+Properties.h │ │ │ └── GVUserDefaults+Properties.m │ │ ├── NSString │ │ │ ├── NSString+Additions.h │ │ │ └── NSString+Additions.m │ │ ├── NSURL+QueryDictionary │ │ │ ├── NSURL+QueryDictionary.h │ │ │ └── NSURL+QueryDictionary.m │ │ ├── UIResponder │ │ │ ├── UIResponder+Router.h │ │ │ └── UIResponder+Router.m │ │ ├── UIView │ │ │ ├── UIView+Additions.h │ │ │ └── UIView+Additions.m │ │ └── UIViewController │ │ │ ├── UIViewController+Custom.h │ │ │ └── UIViewController+Custom.m │ ├── DBManager │ │ ├── LaunchScreenAdDBManager.h │ │ ├── LaunchScreenAdDBManager.m │ │ ├── UserDBManager.h │ │ └── UserDBManager.m │ ├── Entities │ │ ├── CategoryEntity.h │ │ ├── CategoryEntity.m │ │ ├── CommentEntity.h │ │ ├── CommentEntity.m │ │ ├── LaunchScreenAdEntity.h │ │ ├── LaunchScreenAdEntity.m │ │ ├── NotificationEntity.h │ │ ├── NotificationEntity.m │ │ ├── PaginationEntity.h │ │ ├── PaginationEntity.m │ │ ├── TopicEntity.h │ │ ├── TopicEntity.m │ │ ├── UserEntity.h │ │ └── UserEntity.m │ └── Helper │ │ ├── BaseHelper.h │ │ └── BaseHelper.m ├── Views │ ├── Base │ │ ├── BaseView.h │ │ ├── BaseView.m │ │ ├── BaseWebView.h │ │ ├── BaseWebView.m │ │ ├── BubbleButton.h │ │ ├── BubbleButton.m │ │ ├── SkipButton.h │ │ └── SkipButton.m │ ├── Comment │ │ ├── CommentListViewController.h │ │ └── CommentListViewController.m │ ├── LaunchAd │ │ ├── LaunchScreenAdView.h │ │ └── LaunchScreenAdView.m │ ├── Me │ │ └── Me.storyboard │ ├── Notification │ │ ├── NotificationListCell.h │ │ ├── NotificationListCell.m │ │ ├── NotificationListTableView.h │ │ └── NotificationListTableView.m │ ├── Passport │ │ └── Passport.storyboard │ ├── Settings │ │ └── Settings.storyboard │ ├── Topic │ │ ├── EmptyTopicView.h │ │ ├── EmptyTopicView.m │ │ ├── Topic.storyboard │ │ ├── TopicListCell.h │ │ ├── TopicListCell.m │ │ ├── TopicListTableView.h │ │ ├── TopicListTableView.m │ │ ├── TopicSearchBar.h │ │ ├── TopicSearchBar.m │ │ ├── TopicVoteView.h │ │ └── TopicVoteView.m │ └── User │ │ └── UserProfile.storyboard └── main.m ├── PHPHubTests ├── Info.plist └── PHPHubTests.m ├── Podfile ├── Podfile.lock └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # Ignore secret constant file 46 | PHPHub/Constants/SecretConstant.h 47 | 48 | # Ignore Config Plist File 49 | PHPHub/PushConfig.plist -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Paul King 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. -------------------------------------------------------------------------------- /PHPHub.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PHPHub.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PHPHub/Apis/AdApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // AdApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | 11 | @interface AdApi : BaseApi 12 | - (id)getAdvertsLaunchScreen:(BaseResultBlock)block; 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Apis/AdApi.m: -------------------------------------------------------------------------------- 1 | // 2 | // AdApi.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "AdApi.h" 10 | #import "LaunchScreenAdEntity.h" 11 | 12 | @implementation AdApi 13 | 14 | - (id)getAdvertsLaunchScreen:(BaseResultBlock)block { 15 | NSString *urlPath = @"adverts/launch_screen"; 16 | 17 | BaseRequestSuccessBlock successBlock = ^(NSURLSessionDataTask * __unused task, id rawData) { 18 | NSMutableDictionary *data = [(NSDictionary *)rawData mutableCopy]; 19 | data[@"entities"] = [LaunchScreenAdEntity arrayOfEntitiesFromArray:data[@"data"]]; 20 | if (block) block(data, nil); 21 | }; 22 | 23 | BaseRequestFailureBlock failureBlock = ^(NSURLSessionDataTask *__unused task, NSError *error) { 24 | if (block) block(nil, error); 25 | }; 26 | 27 | return [[BaseApi clientGrantInstance] GET:urlPath 28 | parameters:nil 29 | success:successBlock 30 | failure:failureBlock]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PHPHub/Apis/CategoryApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/10/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | #import "CategoryEntity.h" 11 | 12 | @interface CategoryApi : BaseApi 13 | - (id)getAllTopicCategory:(BaseResultBlock)block; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Apis/CategoryApi.m: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryApi.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/10/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CategoryApi.h" 10 | 11 | @implementation CategoryApi 12 | 13 | - (id)getAllTopicCategory:(BaseResultBlock)block { 14 | NSString *urlPath = @"categories"; 15 | 16 | BaseRequestSuccessBlock successBlock = ^(NSURLSessionDataTask * __unused task, id rawData) { 17 | NSMutableDictionary *data = [(NSDictionary *)rawData mutableCopy]; 18 | if (data[@"data"]) { 19 | data[@"entities"] = [CategoryEntity arrayOfEntitiesFromArray:data[@"data"]]; 20 | } 21 | if (block) block(data, nil); 22 | }; 23 | 24 | BaseRequestFailureBlock failureBlock = ^(NSURLSessionDataTask *__unused task, NSError *error) { 25 | if (block) block(nil, error); 26 | }; 27 | 28 | return [[BaseApi clientGrantInstance] GET:urlPath 29 | parameters:nil 30 | success:successBlock 31 | failure:failureBlock]; 32 | } 33 | @end 34 | -------------------------------------------------------------------------------- /PHPHub/Apis/NotificationApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/13/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | #import "NotificationEntity.h" 11 | 12 | @interface NotificationApi : BaseApi 13 | - (id)getNotificationList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 14 | - (id)getUnreadNotificationCount:(BaseResultBlock)block; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Apis/NotificationApi.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationApi.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/13/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "NotificationApi.h" 10 | 11 | @implementation NotificationApi 12 | - (id)getNotificationList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 13 | NSString *urlPath = [NSString stringWithFormat:@"me/notifications?include=from_user,topic&per_page=20&page=%ld", (long)pageIndex]; 14 | 15 | BaseRequestSuccessBlock successBlock = ^(NSURLSessionDataTask * __unused task, id rawData) { 16 | NSMutableDictionary *data = [(NSDictionary *)rawData mutableCopy]; 17 | data[@"entities"] = [NotificationEntity arrayOfEntitiesFromArray:data[@"data"]]; 18 | data[@"pagination"] = [PaginationEntity entityFromDictionary:data[@"meta"][@"pagination"]]; 19 | if (block) block(data, nil); 20 | }; 21 | 22 | BaseRequestFailureBlock failureBlock = ^(NSURLSessionDataTask *__unused task, NSError *error) { 23 | if (block) block(nil, error); 24 | }; 25 | 26 | return [[BaseApi loginTokenGrantInstance] GET:urlPath 27 | parameters:nil 28 | success:successBlock 29 | failure:failureBlock]; 30 | } 31 | 32 | - (id)getUnreadNotificationCount:(BaseResultBlock)block { 33 | NSString *urlPath = [NSString stringWithFormat:@"me/notifications/count"]; 34 | 35 | BaseRequestSuccessBlock successBlock = ^(NSURLSessionDataTask * __unused task, id rawData) { 36 | NSMutableDictionary *data = [(NSDictionary *)rawData mutableCopy]; 37 | if (block) block(data, nil); 38 | }; 39 | 40 | BaseRequestFailureBlock failureBlock = ^(NSURLSessionDataTask *__unused task, NSError *error) { 41 | if (block) block(nil, error); 42 | }; 43 | 44 | return [[BaseApi loginTokenGrantInstance] GET:urlPath 45 | parameters:nil 46 | success:successBlock 47 | failure:failureBlock]; 48 | } 49 | @end 50 | -------------------------------------------------------------------------------- /PHPHub/Apis/TopicApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | #import "TopicEntity.h" 11 | #import "CommentEntity.h" 12 | 13 | @interface TopicApi : BaseApi 14 | 15 | - (id)getAll:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 16 | - (id)getExcellentTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 17 | - (id)getNewestTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 18 | - (id)getHotsTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 19 | - (id)getNoReplyTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 20 | - (id)getJobTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 21 | - (id)getWiKiList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 22 | - (id)getTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 23 | - (id)getVotedTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 24 | - (id)getTopicById:(NSInteger)topicId callback:(BaseResultBlock)block; 25 | - (id)addCommentToTopic:(CommentEntity *)comment withBlock:(BaseResultBlock)block; 26 | - (id)createTopic:(TopicEntity *)entity withBlock:(BaseResultBlock)block; 27 | - (id)voteUpTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block; 28 | - (id)voteDownTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block; 29 | @end 30 | -------------------------------------------------------------------------------- /PHPHub/Apis/UserApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | #import "UserEntity.h" 11 | 12 | @interface UserApi : BaseApi 13 | - (id)getCurrentUserData:(BaseResultBlock)block; 14 | - (id)getUserById:(NSNumber *)userId callback:(BaseResultBlock)block; 15 | - (id)loginWithUserName:(NSString *)username loginToken:(NSString *)loginToken block:(BaseResultBlock)block; 16 | - (id)updateUserProfile:(UserEntity *)user withBlock:(BaseResultBlock)block; 17 | @end 18 | -------------------------------------------------------------------------------- /PHPHub/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BaseTabBarViewController.h" 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | @property (strong, nonatomic) BaseTabBarViewController *tabBarViewController; 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseApi.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseApi.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "AFHTTPSessionManager.h" 10 | #import "APIRequestHandler.h" 11 | 12 | typedef void (^ BaseResultBlock)(id data, NSError *error); 13 | typedef void (^ BaseRequestSuccessBlock)(NSURLSessionDataTask *task, id responseObject); 14 | typedef void (^ BaseRequestFailureBlock)(NSURLSessionDataTask *task, NSError *error); 15 | typedef void (^ BaseRequestConstructingBodyBlock)(id formData); 16 | 17 | @interface BaseApi : AFHTTPSessionManager 18 | 19 | @property(strong,nonatomic) APIRequestHandler* handler; 20 | 21 | #pragma mark - Share Instance 22 | 23 | + (instancetype)loginTokenGrantInstance; 24 | + (instancetype)clientGrantInstance; 25 | 26 | #pragma mark - Public Method 27 | 28 | - (void)setUpLoginTokenGrantRequest; 29 | - (void)setUpClientGrantRequest; 30 | 31 | #pragma mark - Shared/Inherit Method 32 | 33 | - (id)create:(id)entity withBlock:(BaseResultBlock)block; 34 | - (id)update:(id)entity withBlock:(BaseResultBlock)block; 35 | - (id)upvote:(id)entity withBlock:(BaseResultBlock)block; 36 | @end 37 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseApi.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseApi.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseApi.h" 10 | #import "AccessTokenHandler.h" 11 | 12 | @implementation BaseApi 13 | #pragma mark - Share Instance 14 | 15 | + (instancetype)loginTokenGrantInstance { 16 | static BaseApi *_passwordGrantInstance = nil; 17 | static dispatch_once_t passwordGrantOnceToken; 18 | dispatch_once(&passwordGrantOnceToken, ^{ 19 | _passwordGrantInstance = [[BaseApi alloc] initWithBaseURL:[NSURL URLWithString:APIBaseURL]]; 20 | 21 | [_passwordGrantInstance prepareForCommonRequest]; 22 | [_passwordGrantInstance setUpLoginTokenGrantRequest]; 23 | }); 24 | return _passwordGrantInstance; 25 | } 26 | 27 | + (instancetype)clientGrantInstance { 28 | static BaseApi *_clientGrantInstance = nil; 29 | static dispatch_once_t clientGrantOnceToken; 30 | dispatch_once(&clientGrantOnceToken, ^{ 31 | _clientGrantInstance = [[BaseApi alloc] initWithBaseURL:[NSURL URLWithString:APIBaseURL]]; 32 | 33 | [_clientGrantInstance prepareForCommonRequest]; 34 | [_clientGrantInstance setUpClientGrantRequest]; 35 | }); 36 | return _clientGrantInstance; 37 | } 38 | 39 | #pragma mark - Helper 40 | 41 | - (void)prepareForCommonRequest { 42 | NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleShortVersionString"]; 43 | NSString *buildNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey: (NSString *)kCFBundleVersionKey]; 44 | self.responseSerializer = [AFJSONResponseSerializer serializer]; 45 | [self.requestSerializer setValue:@"application/vnd.PHPHub.v1+json" forHTTPHeaderField:@"Accept"]; 46 | [self.requestSerializer setValue:@"iOS" forHTTPHeaderField:@"X-Client-Platform"]; 47 | [self.requestSerializer setValue:version forHTTPHeaderField:@"X-Client-Version"]; 48 | [self.requestSerializer setValue:buildNumber forHTTPHeaderField:@"X-Client-Build"]; 49 | [self.requestSerializer setValue:@"" forHTTPHeaderField:@"Cookie"]; 50 | self.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; 51 | 52 | self.handler = [[APIRequestHandler alloc] init]; 53 | [self.handler registerNotifications]; 54 | } 55 | 56 | - (void)setUpLoginTokenGrantRequest { 57 | [self.requestSerializer setValue:[AccessTokenHandler getLoginTokenGrantAccessToken] 58 | forHTTPHeaderField:@"Authorization"]; 59 | self.handler.grantType = @"login_token"; 60 | } 61 | 62 | - (void)setUpClientGrantRequest { 63 | [self.requestSerializer setValue:[AccessTokenHandler getClientGrantAccessTokenFromLocal] 64 | forHTTPHeaderField:@"Authorization"]; 65 | self.handler.grantType = @"client_credentials"; 66 | } 67 | 68 | #pragma mark - Abstract Method 69 | 70 | - (id)create:(id)entity withBlock:(BaseResultBlock)block { 71 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 72 | [self doesNotRecognizeSelector:_cmd]; 73 | return nil; 74 | } 75 | 76 | - (id)update:(id)entity withBlock:(BaseResultBlock)block { 77 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 78 | [self doesNotRecognizeSelector:_cmd]; 79 | return nil; 80 | } 81 | 82 | - (id)upvote:(id)entity withBlock:(BaseResultBlock)block { 83 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 84 | [self doesNotRecognizeSelector:_cmd]; 85 | return nil; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseDBManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseDBManager.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FMDatabase.h" 12 | #import "FMDatabaseAdditions.h" 13 | #import "MTLModel.h" 14 | #import "FMDBMigrationManager.h" 15 | 16 | #define DefaultDatabaseFileName @"MainDataBase.sqlite" 17 | 18 | @interface BaseDBManager : NSObject 19 | @property(strong, nonatomic)FMDatabase *db; 20 | 21 | + (instancetype)sharedInstance; 22 | 23 | + (NSArray *)columnValuesForUpdate:(MTLModel *)model; 24 | + (BOOL)isExists:(MTLModel *)model; 25 | + (NSNumber *)getDataCount:(Class)objectClass; 26 | 27 | + (void)insertOnDuplicateUpdate:(MTLModel *)model; 28 | + (id)findById:(NSString *)primary_id withClass:(Class)objectClass; 29 | 30 | + (id)findUsingPrimaryKeys:(MTLModel *)model; 31 | + (NSArray *)findByColumn:(NSString *)column columnValue:(NSString *)value withClass:(Class)objectClass; 32 | + (NSArray *)findRandomByDictionary:(NSDictionary *)columnDictionary withClass:(Class)objectClass; 33 | + (id)updateDate:(NSDictionary *)columnDictionary withClass:(Class)objectClass; 34 | + (NSNumber *)getMaxColumnIdWithClass:(Class)objectClass column:(NSString *)column; 35 | @end 36 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "MTLModel.h" 10 | #import "MTLJSONAdapter.h" 11 | #import "MTLValueTransformer.h" 12 | #import "NSValueTransformer+MTLPredefinedTransformerAdditions.h" 13 | #import "MTLFMDBAdapter.h" 14 | 15 | @interface BaseEntity : MTLModel 16 | #pragma mark - Class Methods to create Entity 17 | 18 | + (NSDateFormatter *)dateFormatter; 19 | 20 | + (id)entityFromDictionary:(NSDictionary *)data; 21 | + (NSArray *)arrayOfEntitiesFromArray:(NSArray *)array; 22 | 23 | #pragma mark - Instance Method 24 | 25 | - (NSDictionary *)transformToDictionary; 26 | + (NSArray *)transformToArray:(NSArray *)array; 27 | @end 28 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | @implementation BaseEntity 12 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 13 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 14 | [self doesNotRecognizeSelector:_cmd]; 15 | return nil; 16 | } 17 | 18 | #pragma mark - Common Public Methods 19 | 20 | - (NSDictionary *)transformToDictionary { 21 | return [MTLJSONAdapter JSONDictionaryFromModel:self]; 22 | } 23 | 24 | + (NSArray *)transformToArray:(NSArray *)array { 25 | return [MTLJSONAdapter JSONArrayFromModels:array]; 26 | } 27 | 28 | + (id)entityFromDictionary:(NSDictionary *)data { 29 | NSError *error; 30 | id entity = [MTLJSONAdapter modelOfClass:self.class fromJSONDictionary:data error:&error]; 31 | 32 | if (error) { 33 | NSLog(@"Couldn't convert JSON to Entity: %@", error); 34 | return nil; 35 | } 36 | return entity; 37 | } 38 | 39 | + (NSArray *)arrayOfEntitiesFromArray:(NSArray *)array { 40 | NSError *error; 41 | NSArray *arrayOfEntities = [MTLJSONAdapter modelsOfClass:[self class] 42 | fromJSONArray:array 43 | error:&error]; 44 | if (error) { 45 | NSLog(@"Couldn't convert app infos JSON to ChoosyAppInfo models: %@", error); 46 | return nil; 47 | } 48 | return arrayOfEntities; 49 | } 50 | 51 | #pragma mark - Share Property convertor 52 | 53 | + (NSValueTransformer *)createdAtJSONTransformer { 54 | return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) { 55 | return [self.dateFormatter dateFromString:str]; 56 | } reverseBlock:^(NSDate *date) { 57 | return [self.dateFormatter stringFromDate:date]; 58 | }]; 59 | } 60 | 61 | + (NSValueTransformer *)updatedAtJSONTransformer { 62 | return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) { 63 | return [self.dateFormatter dateFromString:str];; 64 | } reverseBlock:^(NSDate *date) { 65 | return [self.dateFormatter stringFromDate:date]; 66 | }]; 67 | } 68 | 69 | #pragma mark - MTLModel Overwrite 70 | 71 | - (NSDictionary *)dictionaryValue { 72 | NSMutableDictionary *modifiedDictionaryValue = [[super dictionaryValue] mutableCopy]; 73 | 74 | for (NSString *originalKey in [super dictionaryValue]) { 75 | if ([self valueForKey:originalKey] == nil ) { 76 | 77 | if ([[self valueForKey:originalKey] isKindOfClass:[NSString class]]) { 78 | [modifiedDictionaryValue setObject:@"" forKey:originalKey]; 79 | } 80 | } 81 | } 82 | 83 | return [modifiedDictionaryValue copy]; 84 | } 85 | 86 | #pragma mark - Helpers 87 | 88 | + (NSDateFormatter *)dateFormatter { 89 | static NSDateFormatter *_formatter; 90 | 91 | if (!_formatter) { 92 | _formatter = [NSDateFormatter new]; 93 | _formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; 94 | } 95 | return _formatter; 96 | } 97 | 98 | @end -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseModel : NSObject 12 | + (instancetype)Instance; 13 | 14 | - (id)create:(id)entity withBlock:(BaseResultBlock)block; 15 | - (id)update:(id)entity withBlock:(BaseResultBlock)block; 16 | - (id)upvote:(id)entity withBlock:(BaseResultBlock)block; 17 | @end 18 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/BaseModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | 11 | @implementation BaseModel 12 | + (instancetype)Instance { 13 | return [[self alloc] init]; 14 | } 15 | 16 | - (id)create:(id)entity withBlock:(BaseResultBlock)block { 17 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 18 | [self doesNotRecognizeSelector:_cmd]; 19 | return nil; 20 | } 21 | 22 | - (id)update:(id)entity withBlock:(BaseResultBlock)block { 23 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 24 | [self doesNotRecognizeSelector:_cmd]; 25 | return nil; 26 | } 27 | 28 | - (id)upvote:(id)entity withBlock:(BaseResultBlock)block { 29 | NSLog(@"You must override %@ in a subclass",NSStringFromSelector(_cmd)); 30 | [self doesNotRecognizeSelector:_cmd]; 31 | return nil; 32 | } 33 | @end 34 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/CurrentUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // CurrentUser.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UserEntity.h" 11 | #import "UserModel.h" 12 | #import "UserDBManager.h" 13 | 14 | @interface CurrentUser : NSObject 15 | 16 | @property (nonatomic, copy) NSNumber *userId; 17 | @property (nonatomic, strong) UserEntity *userInfo; 18 | + (CurrentUser *)Instance; 19 | - (BOOL)isLogin; 20 | - (BOOL)hasClientToken; 21 | - (void)updateCurrentUserInfoIfNeeded; 22 | - (void)saveUser:(UserEntity *)user; 23 | - (void)setupClientRequestState:(BaseResultBlock)block; 24 | - (void)checkNoticeCount; 25 | - (void)logOut; 26 | - (NSString *)userLabel; 27 | @end 28 | -------------------------------------------------------------------------------- /PHPHub/BaseClasses/CurrentUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // CurrentUser.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CurrentUser.h" 10 | #import "AccessTokenHandler.h" 11 | #import "JpushHandler.h" 12 | #import "NotificationModel.h" 13 | #import "SAMKeychain.h" 14 | 15 | @implementation CurrentUser 16 | + (CurrentUser *)Instance { 17 | static dispatch_once_t once; 18 | static CurrentUser *sharedInstance; 19 | dispatch_once(&once, ^{ 20 | sharedInstance = [[CurrentUser alloc] init]; 21 | }); 22 | return sharedInstance; 23 | } 24 | 25 | - (BOOL)isLogin { 26 | return (self.userId && self.userId.intValue > 0); 27 | } 28 | 29 | - (BOOL)hasClientToken { 30 | return [NSString isStringEmpty:[GVUserDefaults standardUserDefaults].userClientToken]; 31 | } 32 | 33 | - (void)saveUser:(UserEntity *)user { 34 | [UserDBManager insertOnDuplicateUpdate:user]; 35 | [JpushHandler sendUserIdToAlias]; 36 | } 37 | 38 | - (void)updateCurrentUserInfoIfNeeded { 39 | if ([[CurrentUser Instance] isLogin]) { 40 | [[UserModel Instance] getCurrentUserData:nil]; 41 | } 42 | } 43 | 44 | - (NSNumber *)userId { 45 | return [GVUserDefaults standardUserDefaults].currentUserId; 46 | } 47 | 48 | - (UserEntity *)userInfo { 49 | if (!self.userId) return nil; 50 | 51 | return [UserDBManager findByUserId:self.userId]; 52 | } 53 | 54 | - (void)setupClientRequestState:(BaseResultBlock)block { 55 | [AccessTokenHandler fetchClientGrantTokenWithRetryTimes:3 callback:block]; 56 | } 57 | 58 | - (void)checkNoticeCount { 59 | if ([[CurrentUser Instance] isLogin]) { 60 | [[NotificationModel Instance] getUnreadNotificationCount:^(id data, NSError *error) { 61 | if (!error) { 62 | NSNumber *unreadCount = data[@"count"]; 63 | [[UIApplication sharedApplication] setApplicationIconBadgeNumber:unreadCount.integerValue]; 64 | [[NSNotificationCenter defaultCenter] postNotificationName:UpdateNoticeCount object:nil userInfo:@{@"unreadCount":unreadCount}]; 65 | } 66 | }]; 67 | } 68 | } 69 | 70 | - (void)logOut { 71 | [SAMKeychain deletePasswordForService:KeyChainService account:KeyChainAccount]; 72 | [GVUserDefaults standardUserDefaults].currentUserId = nil; 73 | [JpushHandler sendEmptyAlias]; 74 | } 75 | 76 | - (NSString *)userLabel { 77 | return self.isLogin ? [NSString stringWithFormat:@"user_%@_%@", [CurrentUser Instance].userId, [[CurrentUser Instance] userInfo].username] : @"non-logged-in"; 78 | } 79 | @end 80 | -------------------------------------------------------------------------------- /PHPHub/Constants/APIConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // APIConstant.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #define APIAccessTokenURL [NSString stringWithFormat:@"%@%@", APIBaseURL, @"/oauth/access_token"] 10 | #define QiniuUploadTokenIdentifier @"QiniuUploadTokenIdentifier" 11 | 12 | #if DEBUG 13 | #define APIBaseURL @"http://staging.phphub.org/v1" 14 | #else 15 | #define APIBaseURL @"https://api.phphub.org/v1" 16 | #endif 17 | 18 | #define PHPHubHost @"phphub.org" 19 | #define PHPHubUrl @"https://phphub.org/" 20 | #define GitHubURL @"https://github.com/" 21 | #define TwitterURL @"https://twitter.com/" 22 | #define ProjectURL @"https://github.com/aufree/phphub-ios" 23 | #define AboutPageURL @"https://phphub.org/about" 24 | #define ESTGroupURL @"http://est-group.org" 25 | #define AboutTheAuthorURL @"https://github.com/aufree" 26 | #define PHPHubGuide @"http://7xnqwn.com1.z0.glb.clouddn.com/index.html" 27 | #define PHPHubTopicURL @"https://phphub.org/topics/" 28 | #define SinaRedirectURL @"http://sns.whalecloud.com/sina2/callback" 29 | 30 | #define UpdateNoticeCount @"UpdateNoticeCount" 31 | #define KeyChainService @"PHPHubService" 32 | #define KeyChainAccount @"com.PHPHub.keychain" 33 | -------------------------------------------------------------------------------- /PHPHub/Constants/DebugConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // DebugConstant.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | 10 | #define DEBUG_HTTP NO 11 | #define DEBUG_ANALYTICS NO 12 | 13 | 14 | #ifdef DEBUG 15 | #define debugLog(...) NSLog(__VA_ARGS__) 16 | #define debugMethod() NSLog(@"%s", __func__) 17 | #define NSLog(...) NSLog(__VA_ARGS__) 18 | #else 19 | #define debugLog(...) 20 | #define debugMethod() 21 | #define NSLog(...) 22 | #endif 23 | -------------------------------------------------------------------------------- /PHPHub/Constants/SecretConstant.example.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecretConstant.example.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #if DEBUG 10 | #define Client_id @"kHOugsx4dmcXwvVbmLkd" 11 | #define Client_secret @"PuuFCrF94MloSbSkxpwS" 12 | #else 13 | #define Client_id @"" // Set up a client id for production environment 14 | #define Client_secret @"" // Set up a client secret for production environment 15 | #endif 16 | 17 | #define UMENG_APPKEY @"" // Set up UMEng App Key 18 | #define UMENG_QQ_ID @"" // Set up QQ id 19 | #define UMENG_QQ_APPKEY @"" // Set up QQ appkey 20 | #define WX_APP_ID @"" // Set up wechat app id 21 | #define WX_APP_SECRET @"" // Set up wechat app secret 22 | #define JPush_APP_KEY @"" // Set up Jpush App Key 23 | #define TRACKING_ID @"" // Set up google anlytics tracking id -------------------------------------------------------------------------------- /PHPHub/Constants/UIConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIConstant.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #define FontName @"Helvetica Neue" 10 | #define BoldFontName @"Helvetica-Bold" 11 | 12 | // Main Screen 13 | #define SCREEN_HEIGHT [[UIScreen mainScreen]bounds].size.height 14 | #define SCREEN_WIDTH [[UIScreen mainScreen]bounds].size.width 15 | #define ORIGINAL_MAX_WIDTH 640.0f 16 | 17 | // RGB Color 18 | #define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] 19 | #define RGB(r,g,b) RGBA(r,g,b,1.0f) 20 | 21 | #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 22 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) 23 | #define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0) 24 | 25 | #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT)) 26 | #define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT)) 27 | 28 | #define IS_IPHONE_4_OR_LESS (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0) 29 | #define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0) 30 | #define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0) 31 | #define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0) -------------------------------------------------------------------------------- /PHPHub/Controllers/Essential/EssentialListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EssentialListViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EssentialListViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Forum/TopicListContainerViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListContainerViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "ViewPagerController.h" 12 | 13 | @interface TopicListContainerViewController : ViewPagerController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Forum/TopicListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TopicListTableView.h" 11 | 12 | typedef NS_ENUM(NSInteger, TopicListType) { 13 | TopicListTypeNewest = 0, 14 | TopicListTypeHots = 1, 15 | TopicListTypeNoReply = 2, 16 | TopicListTypeJob = 3, 17 | TopicListTypeVoted = 4, 18 | TopicListTypeNormal = 5, 19 | }; 20 | 21 | @interface TopicListViewController : UIViewController 22 | @property (nonatomic) TopicListType topicListType; 23 | @property (nonatomic, assign) NSInteger userId; 24 | @property (nonatomic, strong) TopicListTableView *tableView; 25 | @property (nonatomic, assign) BOOL isFromTopicContainer; 26 | @end 27 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Me/MeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MeViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/23/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MeViewController : UITableViewController 12 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 13 | @property (weak, nonatomic) IBOutlet UILabel *usernameLabel; 14 | @property (weak, nonatomic) IBOutlet UILabel *userIntroLabel; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Notification/NotificationListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationListViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NotificationListTableView.h" 11 | 12 | @interface NotificationListViewController : UIViewController 13 | @property (nonatomic, strong) NotificationListTableView *tableView; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Notification/NotificationListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationListViewController.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "NotificationListViewController.h" 10 | #import "NotificationListCell.h" 11 | #import "NotificationEntity.h" 12 | #import "NotificationModel.h" 13 | 14 | @interface NotificationListViewController () 15 | @property (nonatomic, strong) NSMutableArray *notificationEntities; 16 | @property (nonatomic, strong) PaginationEntity *pagination; 17 | @end 18 | 19 | @implementation NotificationListViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.tableView = [[NotificationListTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 25 | [self.view addSubview:self.tableView]; 26 | self.navigationItem.title = @"我的消息"; 27 | [self setupHeaderView]; 28 | [self.tableView.mj_header beginRefreshing]; 29 | } 30 | 31 | - (void)setupHeaderView { 32 | MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefreshing)]; 33 | header.lastUpdatedTimeLabel.hidden = YES; 34 | header.stateLabel.font = [UIFont fontWithName:FontName size:13]; 35 | self.self.tableView.mj_header = header; 36 | } 37 | 38 | #pragma mark Get Topic Data 39 | 40 | - (void)headerRefreshing { 41 | __weak typeof(self) weakself = self; 42 | BaseResultBlock callback =^ (NSDictionary *data, NSError *error) { 43 | if (!error) { 44 | weakself.notificationEntities = data[@"entities"]; 45 | weakself.pagination = data[@"pagination"]; 46 | [weakself.tableView reloadData]; 47 | [[CurrentUser Instance] checkNoticeCount]; 48 | } 49 | 50 | [weakself.self.tableView.mj_header endRefreshing]; 51 | if (weakself.pagination.totalPages > 1) { 52 | MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRereshing)]; 53 | footer.stateLabel.font = [UIFont fontWithName:FontName size:13]; 54 | self.tableView.mj_footer = footer; 55 | } 56 | }; 57 | 58 | [self fetchDataSource:callback atPage:1]; 59 | } 60 | 61 | - (void)footerRereshing { 62 | NSUInteger maxPage = self.pagination.totalPages; 63 | NSUInteger nextPage = self.pagination.currentPage + 1; 64 | 65 | if (nextPage <= maxPage) { 66 | __weak typeof(self) weakself = self; 67 | BaseResultBlock callback = ^(NSDictionary *data, NSError *error) { 68 | if (!error) { 69 | NSArray *newData = [data objectForKey:@"entities"]; 70 | 71 | [weakself.notificationEntities addObjectsFromArray:newData]; 72 | weakself.pagination = data[@"pagination"]; 73 | [weakself.tableView reloadData]; 74 | } 75 | [weakself.tableView.mj_footer endRefreshing]; 76 | }; 77 | 78 | [self fetchDataSource:callback atPage:nextPage]; 79 | } else { 80 | [self.tableView.mj_footer endRefreshingWithNoMoreData]; 81 | } 82 | 83 | } 84 | 85 | - (void)setNotificationEntities:(NSMutableArray *)notificationEntities { 86 | _notificationEntities = notificationEntities; 87 | self.tableView.notificationEntities = _notificationEntities; 88 | } 89 | 90 | - (void)fetchDataSource:(BaseResultBlock)callback atPage:(NSUInteger)atPage { 91 | [[NotificationModel Instance] getNotificationList:callback atPage:atPage]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Passport/LoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "QRCodeReaderDelegate.h" 12 | #import "QRCodeReaderViewController.h" 13 | 14 | @protocol LoginViewControllerDelegate 15 | - (void)updateMeView; 16 | @end 17 | 18 | @interface LoginViewController : UIViewController 19 | @property (nonatomic, weak) id delegate; 20 | @property (nonatomic, copy) void (^completeLoginBlock)(void); 21 | @end 22 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Settings/SettingsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/4/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SettingsViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Settings/SettingsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsViewController.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/4/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "SettingsViewController.h" 10 | #import "TOWebViewController.h" 11 | 12 | #import "UMFeedback.h" 13 | #import "WCAlertView.h" 14 | 15 | @interface SettingsViewController () 16 | 17 | @end 18 | 19 | @implementation SettingsViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.navigationItem.title = @"设置"; 25 | } 26 | 27 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 28 | return 12.0f; 29 | } 30 | 31 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 32 | return section == 2 ? 100.0f : 0.1f; 33 | } 34 | 35 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 36 | NSInteger section = indexPath.section; 37 | NSInteger row = indexPath.row; 38 | UIViewController *vc; 39 | 40 | if (section == 0) { 41 | [self jumpToUMFeedBack]; 42 | } else if (section == 1) { 43 | switch (row) { 44 | case 0: 45 | vc = [[TOWebViewController alloc] initWithURLString:ProjectURL]; 46 | break; 47 | case 1: 48 | vc = [[TOWebViewController alloc] initWithURLString:AboutTheAuthorURL]; 49 | break; 50 | case 2: 51 | vc = [[TOWebViewController alloc] initWithURLString:AboutPageURL]; 52 | break; 53 | case 3: 54 | vc = [[TOWebViewController alloc] initWithURLString:ESTGroupURL]; 55 | break; 56 | } 57 | } else if (section == 2) { 58 | [self showLogoutAlertView]; 59 | } 60 | 61 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 62 | 63 | if (vc) { 64 | [self.navigationController pushViewController:vc animated:YES]; 65 | } 66 | } 67 | 68 | - (void)jumpToUMFeedBack { 69 | UserEntity *currentUser = [[CurrentUser Instance] userInfo]; 70 | NSString *plain = [NSString stringWithFormat:@"uid:%@ - uname:%@", currentUser.userId, currentUser.username]; 71 | [[UMFeedback sharedInstance] updateUserInfo:@{@"contact": 72 | @{ 73 | @"email": currentUser.email, 74 | @"phone": @"", 75 | @"qq": @"", 76 | @"plain": plain 77 | } 78 | }]; 79 | [self presentViewController:[UMFeedback feedbackModalViewController] animated:YES completion:nil]; 80 | } 81 | 82 | - (void)showLogoutAlertView { 83 | __weak typeof(self) weakSelf = self; 84 | [WCAlertView showAlertWithTitle:@"提示" message:@"您确定要退出当前账号吗?" customizationBlock:nil completionBlock: 85 | ^(NSUInteger buttonIndex, WCAlertView *alertView) { 86 | if (buttonIndex == 1) { 87 | [AnalyticsHandler logEvent:@"退出登录" withCategory:kUserAction label:[CurrentUser Instance].userLabel]; 88 | [weakSelf logout]; 89 | } 90 | } cancelButtonTitle:@"取消" otherButtonTitles:@"退出", nil]; 91 | } 92 | 93 | - (void)logout { 94 | [[CurrentUser Instance] logOut]; 95 | [self.navigationController popViewControllerAnimated:YES]; 96 | } 97 | 98 | @end -------------------------------------------------------------------------------- /PHPHub/Controllers/TabBar/BaseTabBarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseTabBarViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseTabBarViewController : UITabBarController 12 | - (void)setupTabBarItems; 13 | - (void)pushToViewController:(UIViewController *)viewController animated:(BOOL)animated; 14 | - (void)presentToViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^)(void))completion; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Topic/PostTopicViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PostTopicViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PostTopicViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Topic/ReplyTopicViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReplyTopicViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol ReplyTopicViewControllerDelegate 12 | @optional 13 | - (void)jumpToCommentsView; 14 | - (void)reloadCommentListView; 15 | @end 16 | 17 | @interface ReplyTopicViewController : UIViewController 18 | @property (nonatomic, copy) NSNumber *topicId; 19 | @property (nonatomic, weak) id delegate; 20 | @end 21 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Topic/ReplyTopicViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ReplyTopicViewController.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "ReplyTopicViewController.h" 10 | #import "UITextView+Placeholder.h" 11 | #import "TopicModel.h" 12 | 13 | @interface ReplyTopicViewController () 14 | @property (weak, nonatomic) IBOutlet UITextView *commentTextView; 15 | @end 16 | 17 | @implementation ReplyTopicViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | self.navigationItem.title = @"发表回复"; 23 | 24 | [self createRightButtonItem]; 25 | _commentTextView.layer.cornerRadius = 5.0f; 26 | _commentTextView.placeholder = @"请使用 Markdown 格式书写 ;-)"; 27 | [_commentTextView becomeFirstResponder]; 28 | } 29 | 30 | # pragma mark Post Comment 31 | 32 | - (void)createRightButtonItem { 33 | UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"send_icon"] 34 | style:UIBarButtonItemStylePlain 35 | target:self 36 | action:@selector(postTopicCommentToServer)]; 37 | rightBarButtonItem.tintColor = [UIColor colorWithRed:0.502 green:0.776 blue:0.200 alpha:1.000]; 38 | self.navigationItem.rightBarButtonItem = rightBarButtonItem; 39 | } 40 | 41 | - (void)postTopicCommentToServer { 42 | 43 | CommentEntity *comment = [[CommentEntity alloc] init]; 44 | comment.topicId = _topicId; 45 | comment.commentBody = _commentTextView.text; 46 | [AnalyticsHandler logEvent:@"回复帖子" withCategory:kTopicAction label:[NSString stringWithFormat:@"%@ topicId:%@", [CurrentUser Instance].userLabel, _topicId]]; 47 | 48 | [SVProgressHUD show]; 49 | 50 | __weak typeof(self) weakself = self; 51 | BaseResultBlock callback =^(NSDictionary *data, NSError *error) { 52 | if (!error) { 53 | [SVProgressHUD dismiss]; 54 | [weakself.navigationController popViewControllerAnimated:YES]; 55 | if (weakself.delegate) { 56 | if ([weakself.delegate respondsToSelector:@selector(reloadCommentListView)]) { 57 | [weakself.delegate reloadCommentListView]; 58 | } else if ([weakself.delegate respondsToSelector:@selector(jumpToCommentsView)]) { 59 | [weakself.delegate jumpToCommentsView]; 60 | } 61 | } 62 | } else { 63 | [SVProgressHUD showErrorWithStatus:@"回复失败, 请重试"]; 64 | } 65 | self.navigationItem.rightBarButtonItem.enabled = YES; 66 | }; 67 | 68 | if (_commentTextView.text.length > 1) { 69 | self.navigationItem.rightBarButtonItem.enabled = NO; 70 | [[TopicModel Instance] addCommentToTopic:comment withBlock:callback]; 71 | } else { 72 | [SVProgressHUD showErrorWithStatus:@"评论字数至少为两个"]; 73 | } 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /PHPHub/Controllers/Topic/TopicDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicDetailViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/8/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TopicEntity.h" 11 | 12 | @interface TopicDetailViewController : UIViewController 13 | @property (nonatomic, strong) TopicEntity *topic; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Controllers/User/EditUserProfileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // EditUserProfileViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/4/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol EditUserProfileViewControllerDelegate 12 | - (void)refreshUserProfileView; 13 | @end 14 | 15 | @interface EditUserProfileViewController : UITableViewController 16 | @property (nonatomic, weak) id delegate; 17 | @end 18 | -------------------------------------------------------------------------------- /PHPHub/Controllers/User/UserProfileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserProfileViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/2/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UserEntity.h" 11 | 12 | @interface UserProfileViewController : UITableViewController 13 | @property (nonatomic, strong) UserEntity *userEntity; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Controllers/WiKi/WiKiListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WiKiListViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WiKiListViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Controllers/WiKi/WiKiListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // WiKiListViewController.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "WiKiListViewController.h" 10 | #import "TopicListTableView.h" 11 | #import "TopicEntity.h" 12 | #import "TopicModel.h" 13 | 14 | @interface WiKiListViewController () 15 | @property (nonatomic, strong) TopicListTableView *tableView; 16 | @property (nonatomic, strong) NSMutableArray *topicEntites; 17 | @property (nonatomic, strong) PaginationEntity *pagination; 18 | @end 19 | 20 | @implementation WiKiListViewController 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.tableView = [[TopicListTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 25 | self.tableView.topicListTableViewDelegate = self; 26 | [self.view addSubview:self.tableView]; 27 | 28 | self.navigationItem.title = @"社区 WiKi"; 29 | 30 | [self.tableView.mj_header beginRefreshing]; 31 | } 32 | 33 | - (void)headerRefreshing { 34 | __weak typeof(self) weakself = self; 35 | BaseResultBlock callback =^ (NSDictionary *data, NSError *error) { 36 | if (!error) { 37 | weakself.topicEntites = data[@"entities"]; 38 | weakself.pagination = data[@"pagination"]; 39 | [weakself.tableView reloadData]; 40 | } 41 | 42 | [weakself.tableView.mj_header endRefreshing]; 43 | if (weakself.pagination.totalPages > 1) { 44 | [weakself.tableView setupFooterView]; 45 | } 46 | }; 47 | 48 | [self fetchDataSource:callback atPage:1]; 49 | } 50 | 51 | - (void)footerRereshing { 52 | NSUInteger maxPage = self.pagination.totalPages; 53 | NSUInteger nextPage = self.pagination.currentPage + 1; 54 | 55 | if (nextPage <= maxPage) { 56 | __weak typeof(self) weakself = self; 57 | BaseResultBlock callback = ^(NSDictionary *data, NSError *error) { 58 | if (!error) { 59 | NSArray *newData = [data objectForKey:@"entities"]; 60 | 61 | [weakself.topicEntites addObjectsFromArray:newData]; 62 | weakself.pagination = data[@"pagination"]; 63 | [weakself.tableView reloadData]; 64 | } 65 | [weakself.tableView.mj_footer endRefreshing]; 66 | }; 67 | 68 | [self fetchDataSource:callback atPage:nextPage]; 69 | } else { 70 | [self.tableView.mj_footer endRefreshingWithNoMoreData]; 71 | } 72 | 73 | } 74 | 75 | - (void)setTopicEntites:(NSMutableArray *)topicEntites { 76 | _topicEntites = topicEntites; 77 | self.tableView.topicEntites = _topicEntites; 78 | } 79 | 80 | - (void)fetchDataSource:(BaseResultBlock)callback atPage:(NSUInteger)atPage { 81 | [[TopicModel Instance] getWiKiList:callback atPage:atPage]; 82 | } 83 | @end 84 | -------------------------------------------------------------------------------- /PHPHub/Handlers/APIRequestHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // APIRequestHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface APIRequestHandler : NSObject 12 | @property(nonatomic, copy) NSString *grantType; 13 | - (void)registerNotifications; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Handlers/AccessTokenHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // AccessTokenHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AFOAuth2Manager.h" 11 | 12 | @interface AccessTokenHandler : NSObject 13 | 14 | + (void)fetchClientGrantToken; 15 | 16 | + (NSString *)getClientGrantAccessTokenFromLocal; 17 | + (NSString *)getLoginTokenGrantAccessToken; 18 | 19 | + (void)storeClientGrantAccessToken:(NSString *)token; 20 | + (void)storeLoginTokenGrantAccessToken:(NSString *)token; 21 | 22 | + (void)clearToken; 23 | 24 | + (void)fetchClientGrantTokenWithRetryTimes:(NSInteger)times callback:(BaseResultBlock)block; 25 | @end 26 | -------------------------------------------------------------------------------- /PHPHub/Handlers/AccessTokenHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // AccessTokenHandler.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "AccessTokenHandler.h" 10 | #import "SAMKeychain.h" 11 | 12 | @implementation AccessTokenHandler 13 | #pragma mark - Client Grant 14 | 15 | + (NSString *)getClientGrantAccessTokenFromLocal { 16 | NSString *token = [GVUserDefaults standardUserDefaults].userClientToken; 17 | return [NSString stringWithFormat:@"Bearer %@", token]; 18 | } 19 | 20 | + (void)storeClientGrantAccessToken:(NSString *)token { 21 | [GVUserDefaults standardUserDefaults].userClientToken = token; 22 | [[BaseApi clientGrantInstance] setUpClientGrantRequest]; 23 | } 24 | 25 | + (void)fetchClientGrantToken { 26 | NSURL *url = [NSURL URLWithString:APIBaseURL]; 27 | AFOAuth2Client *oauthClient = [AFOAuth2Client clientWithBaseURL:url clientID:Client_id secret:Client_secret]; 28 | 29 | [oauthClient authenticateUsingOAuthWithURLString:APIAccessTokenURL 30 | scope:@"" 31 | success: ^(AFOAuthCredential *credential) { 32 | NSLog(@"oauthClient -- > I have a CLIENT GRANT token! %@", credential.accessToken); 33 | [AccessTokenHandler storeClientGrantAccessToken:credential.accessToken]; 34 | } 35 | failure: ^(NSError *error) { 36 | NSLog(@" oauthClient --> Error: %@", error); 37 | }]; 38 | } 39 | 40 | + (void)fetchClientGrantTokenWithRetryTimes:(NSInteger)times callback:(BaseResultBlock)block { 41 | NSURL *url = [NSURL URLWithString:APIBaseURL]; 42 | AFOAuth2Client *oauthClient = [AFOAuth2Client clientWithBaseURL:url clientID:Client_id secret:Client_secret]; 43 | 44 | [oauthClient authenticateUsingOAuthWithURLString:APIAccessTokenURL 45 | scope:@"" 46 | success: ^(AFOAuthCredential *credential) { 47 | NSLog(@"oauthClient -- > I have a CLIENT GRANT token! %@", credential.accessToken); 48 | [AccessTokenHandler storeClientGrantAccessToken:credential.accessToken]; 49 | if (block) block(@{@"access_token": credential.accessToken}, nil); 50 | } 51 | failure: ^(NSError *error) { 52 | if (times > 0) { 53 | NSInteger newRetryTime = times - 1; 54 | [self fetchClientGrantTokenWithRetryTimes:newRetryTime callback:block]; 55 | } else { 56 | if (block) block(nil, error); 57 | } 58 | NSLog(@" oauthClient --> Error: %@", error); 59 | }]; 60 | } 61 | 62 | #pragma mark - Password Grant 63 | 64 | + (NSString *)getLoginTokenGrantAccessToken { 65 | NSString *token = [SAMKeychain passwordForService:KeyChainService account:KeyChainAccount]; 66 | return [NSString stringWithFormat:@"Bearer %@", token]; 67 | } 68 | 69 | + (void)storeLoginTokenGrantAccessToken:(NSString *)token { 70 | [SAMKeychain setPassword:token forService:KeyChainService account:KeyChainAccount]; 71 | [[BaseApi loginTokenGrantInstance] setUpLoginTokenGrantRequest]; 72 | } 73 | 74 | + (void)clearToken { 75 | [SAMKeychain deletePasswordForService:KeyChainService account:KeyChainAccount]; 76 | [GVUserDefaults standardUserDefaults].userClientToken = nil; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /PHPHub/Handlers/AnalyticsHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyticsHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/21/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define kShare @"用户分享" 12 | #define kUserAction @"用户行为" 13 | #define kTopicAction @"帖子操作" 14 | 15 | @interface AnalyticsHandler : NSObject 16 | + (void)bootup; 17 | + (void)logEvent:(NSString *)event; 18 | + (void)logEvent:(NSString *)event withProperties:(NSDictionary *)dict; 19 | + (void)logEvent:(NSString *)event withCategory:(NSString *)category label:(NSString *)lable; 20 | + (void)logScreen:(NSString *)screenName; 21 | 22 | // Log Time 23 | + (void)startTimeEvent:(NSString *)event; 24 | + (void)endTimedEventForHttp:(NSString *)event; 25 | + (void)endTimedEventForDatabase:(NSString *)event; 26 | + (void)endTimedEvent:(NSString *)event withCategory:(NSString *)category label:(NSString *)label; 27 | @end 28 | -------------------------------------------------------------------------------- /PHPHub/Handlers/ExceptionHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExceptionHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/21/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ExceptionHandler : NSObject 12 | + (void)bootup; 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Handlers/ExceptionHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExceptionHandler.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/21/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "ExceptionHandler.h" 10 | #import 11 | #import 12 | 13 | @implementation ExceptionHandler 14 | 15 | + (void)bootup { 16 | 17 | // Init Crashlitics 18 | [Fabric with:@[[Crashlytics class]]]; 19 | 20 | if ([[CurrentUser Instance] isLogin]) { 21 | [CrashlyticsKit setUserIdentifier:[[CurrentUser Instance].userId stringValue]]; 22 | [CrashlyticsKit setUserName:[[CurrentUser Instance] userInfo].username]; 23 | } 24 | } 25 | 26 | + (void)logEvent:(NSString *)eventName { 27 | [Answers logCustomEventWithName:eventName customAttributes:@{}]; 28 | } 29 | 30 | + (void)logEvent:(NSString *)eventName attributes:(NSDictionary * )attributes { 31 | [Answers logCustomEventWithName:eventName customAttributes:attributes]; 32 | } 33 | 34 | + (void)setObjectValue:(id)value forKey:(NSString *)key { 35 | [[Crashlytics sharedInstance] setObjectValue:value forKey:key]; 36 | } 37 | 38 | + (void)setIntValue:(int)value forKey:(NSString *)key { 39 | [[Crashlytics sharedInstance] setIntValue:value forKey:key]; 40 | } 41 | 42 | + (void)setBoolValue:(BOOL)value forKey:(NSString *)key { 43 | [[Crashlytics sharedInstance] setBoolValue:value forKey:key]; 44 | } 45 | 46 | + (void)setFloatValue:(float)value forKey:(NSString *)key { 47 | [[Crashlytics sharedInstance] setFloatValue:value forKey:key]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /PHPHub/Handlers/JpushHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // JpushHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/16/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "APService.h" 11 | 12 | @interface JpushHandler : NSObject 13 | + (void)setupJpush:(NSDictionary *)launchOptions; 14 | + (void)tagsAliasCallback:(int)iResCode tags:(NSSet *)tags alias:(NSString *)alias; 15 | + (NSString *)logSet:(NSSet *)dic; 16 | + (void)sendUserIdToAlias; 17 | + (void)sendEmptyAlias; 18 | + (void)handleUserInfo:(NSDictionary *)userInfo; 19 | @end 20 | -------------------------------------------------------------------------------- /PHPHub/Handlers/JumpToOtherVCHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // JumpToOtherVCHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/8/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TopicEntity.h" 11 | 12 | @interface JumpToOtherVCHandler : NSObject 13 | + (UIViewController *)getTabbarViewController; 14 | + (void)pushToOtherView:(UIViewController *)vc animated:(BOOL)animated; 15 | + (void)presentToOtherView:(UIViewController *)vc animated:(BOOL)animated completion:(void (^)(void))completion; 16 | + (void)jumpToTopicDetailWithTopic:(TopicEntity *)topic; 17 | + (void)jumpToLoginVC:(void (^)(void))completion; 18 | + (void)jumpToTopicDetailWithTopicId:(NSNumber *)topicId; 19 | + (void)jumpToUserProfileWithUserId:(NSNumber *)userId; 20 | + (void)jumpToCommentListVCWithTopic:(TopicEntity *)topic; 21 | + (void)jumpToWebVCWithUrlString:(NSString *)url; 22 | @end 23 | -------------------------------------------------------------------------------- /PHPHub/Handlers/LaunchScreenAdHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LaunchScreenAdEntity.h" 11 | 12 | @interface LaunchScreenAdHandler : NSObject 13 | @property (nonatomic, strong) LaunchScreenAdEntity *launchScreenAdEntity; 14 | + (void)checkShouldShowLaunchScreenAd; 15 | + (void)showLaunchScreenAd; 16 | + (void)createLaunchScreenAdWithAdEntity:(LaunchScreenAdEntity *)launchScreenAdEntity; 17 | + (void)removeLaunchScreenAd:(BOOL)shouldJumpToOtherVC; 18 | @end 19 | -------------------------------------------------------------------------------- /PHPHub/Handlers/UMengSocialHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // UMengSocialHandler.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/15/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UMSocial.h" 10 | #import "UMSocialQQHandler.h" 11 | #import "UMSocialWechatHandler.h" 12 | #import "UMSocialSinaHandler.h" 13 | 14 | @interface UMengSocialHandler : NSObject 15 | + (void)setup; 16 | + (void)shareWithShareURL:(NSString *)shareURL 17 | shareImageUrl:(NSString *)shareImageUrl 18 | shareTitle:(NSString *)shareTitle 19 | shareText:(NSString *)shareText 20 | presentVC:(UIViewController *)vc 21 | delegate:(id )delegate; 22 | @end 23 | -------------------------------------------------------------------------------- /PHPHub/Handlers/UMengSocialHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // UMengSocialHandler.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/15/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UMengSocialHandler.h" 10 | 11 | @interface UMengSocialHandler () 12 | @end 13 | 14 | @implementation UMengSocialHandler 15 | 16 | + (void)setup { 17 | [UMSocialData setAppKey:UMENG_APPKEY]; 18 | [UMSocialQQHandler setQQWithAppId:UMENG_QQ_ID appKey:UMENG_QQ_APPKEY url:PHPHubUrl]; 19 | [UMSocialWechatHandler setWXAppId:WX_APP_ID appSecret:WX_APP_SECRET url:PHPHubUrl]; 20 | [UMSocialSinaHandler openSSOWithRedirectURL:SinaRedirectURL]; 21 | } 22 | 23 | + (void)shareWithShareURL:(NSString *)shareURL 24 | shareImageUrl:(NSString *)shareImageUrl 25 | shareTitle:(NSString *)shareTitle 26 | shareText:(NSString *)shareText 27 | presentVC:(UIViewController *)vc 28 | delegate:(id )delegate { 29 | 30 | [UMSocialData defaultData].extConfig.title = shareTitle; 31 | // Global share link 32 | [[UMSocialData defaultData].urlResource setResourceType:UMSocialUrlResourceTypeImage url:shareImageUrl]; 33 | // WeChat Timeline Custom 34 | [UMSocialData defaultData].extConfig.wechatTimelineData.url = shareURL; 35 | [UMSocialData defaultData].extConfig.wechatSessionData.url = shareURL; 36 | [UMSocialData defaultData].extConfig.qqData.url = shareURL; 37 | 38 | [UMSocialSnsService presentSnsIconSheetView:vc 39 | appKey:UMENG_APPKEY 40 | shareText:shareText 41 | shareImage:[UIImage imageNamed:@"logo"] 42 | shareToSnsNames:[NSArray arrayWithObjects: 43 | UMShareToWechatSession, 44 | UMShareToWechatTimeline, 45 | UMShareToQQ, 46 | UMShareToSina, 47 | nil] 48 | delegate:delegate]; 49 | } 50 | @end -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "icon_29.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "icon_58.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon_87.png", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "icon_80.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon_120.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "57x57", 35 | "idiom" : "iphone", 36 | "filename" : "icon_57.png", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "size" : "57x57", 41 | "idiom" : "iphone", 42 | "filename" : "icon_114.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon_120-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "icon_180.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "29x29", 59 | "idiom" : "ipad", 60 | "filename" : "icon_29-1.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "icon_58-1.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "40x40", 71 | "idiom" : "ipad", 72 | "filename" : "icon_40.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "icon_80-1.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "50x50", 83 | "idiom" : "ipad", 84 | "filename" : "icon_50.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "50x50", 89 | "idiom" : "ipad", 90 | "filename" : "icon_100.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "72x72", 95 | "idiom" : "ipad", 96 | "filename" : "icon_72.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "72x72", 101 | "idiom" : "ipad", 102 | "filename" : "icon_144.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "76x76", 107 | "idiom" : "ipad", 108 | "filename" : "icon_76.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "76x76", 113 | "idiom" : "ipad", 114 | "filename" : "icon_152.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "83.5x83.5", 119 | "idiom" : "ipad", 120 | "filename" : "167.png", 121 | "scale" : "2x" 122 | } 123 | ], 124 | "info" : { 125 | "version" : 1, 126 | "author" : "xcode" 127 | } 128 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_100.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_114.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_120-1.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_120.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_144.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_152.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_180.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_29-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_29-1.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_29.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_40.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_50.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_57.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_58-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_58-1.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_58.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_72.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_76.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_80-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_80-1.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_80.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/AppIcon.appiconset/icon_87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/AppIcon.appiconset/icon_87.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "back.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/back.imageset/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/back.imageset/back.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/cancel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "cancel.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/cancel.imageset/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/cancel.imageset/cancel.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/estgroup_short_intro.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "estgroup_short_intro.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/estgroup_short_intro.imageset/estgroup_short_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/estgroup_short_intro.imageset/estgroup_short_intro.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icon_180.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/logo.imageset/icon_180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/logo.imageset/icon_180.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/more.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "more_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/more.imageset/more_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/more.imageset/more_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/pure_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "pure_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Base/pure_icon.imageset/pure_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Base/pure_icon.imageset/pure_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/comment_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "comment_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/comment_icon.imageset/comment_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/comment_icon.imageset/comment_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/favorite_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "favorite_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/favorite_icon.imageset/favorite_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/favorite_icon.imageset/favorite_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/ring_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "ring_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/ring_icon.imageset/ring_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/ring_icon.imageset/ring_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/settings_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "settings_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/settings_icon.imageset/settings_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/settings_icon.imageset/settings_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/topic_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "topic_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/topic_icon.imageset/topic_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/topic_icon.imageset/topic_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/watch_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "watch_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Me/watch_icon.imageset/watch_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Me/watch_icon.imageset/watch_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Passport/anonymous_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "anonymous_logo.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Passport/anonymous_logo.imageset/anonymous_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Passport/anonymous_logo.imageset/anonymous_logo.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/comments_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "comments_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/comments_icon.imageset/comments_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/comments_icon.imageset/comments_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/essential_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "essential_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/essential_icon.imageset/essential_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/essential_icon.imageset/essential_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/essential_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "essential_selected_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/essential_selected_icon.imageset/essential_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/essential_selected_icon.imageset/essential_selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/forum_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "forum_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/forum_icon.imageset/forum_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/forum_icon.imageset/forum_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/forum_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "forum_selected_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/forum_selected_icon.imageset/forum_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/forum_selected_icon.imageset/forum_selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/me_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "me_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/me_icon.imageset/me_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/me_icon.imageset/me_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/me_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "me_selected_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/me_selected_icon.imageset/me_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/me_selected_icon.imageset/me_selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/reply_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "reply_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/reply_icon.imageset/reply_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/reply_icon.imageset/reply_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/tabbar_backgroud.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "tabbar_background@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/tabbar_backgroud.imageset/tabbar_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/tabbar_backgroud.imageset/tabbar_background@2x.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/wiki_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "wiki_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/wiki_icon.imageset/wiki_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/wiki_icon.imageset/wiki_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/wiki_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "wiki_selected_icon.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/TabBar/wiki_selected_icon.imageset/wiki_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/TabBar/wiki_selected_icon.imageset/wiki_selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/avatar_placeholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "avatar_placeholder.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/avatar_placeholder.imageset/avatar_placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/avatar_placeholder.imageset/avatar_placeholder.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_downvote_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "big_downvote_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_downvote_icon.imageset/big_downvote_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/big_downvote_icon.imageset/big_downvote_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_downvote_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "big_downvote__selected_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_downvote_selected_icon.imageset/big_downvote__selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/big_downvote_selected_icon.imageset/big_downvote__selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_upvote_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "big_upvote_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_upvote_icon.imageset/big_upvote_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/big_upvote_icon.imageset/big_upvote_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_upvote_selected_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "big_upvote_selected_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/big_upvote_selected_icon.imageset/big_upvote_selected_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/big_upvote_selected_icon.imageset/big_upvote_selected_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/corner_circle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "corner_circle.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/corner_circle.imageset/corner_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/corner_circle.imageset/corner_circle.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/downvote_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "downvote_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/downvote_icon.imageset/downvote_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/downvote_icon.imageset/downvote_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/favorite_blue_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "favorite_blue_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/favorite_blue_icon.imageset/favorite_blue_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/favorite_blue_icon.imageset/favorite_blue_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/link_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "link_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/link_icon.imageset/link_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/link_icon.imageset/link_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/pencil_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "pencil_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/pencil_icon.imageset/pencil_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/pencil_icon.imageset/pencil_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/pencil_square_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "pencil_square_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/pencil_square_icon.imageset/pencil_square_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/pencil_square_icon.imageset/pencil_square_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/sad_face.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "sad_face.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/sad_face.imageset/sad_face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/sad_face.imageset/sad_face.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/send_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "send_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/send_icon.imageset/send_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/send_icon.imageset/send_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/share_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "share_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/share_icon.imageset/share_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/share_icon.imageset/share_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/upvote_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "upvote_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/upvote_icon.imageset/upvote_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/upvote_icon.imageset/upvote_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/vote_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "vote_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/vote_icon.imageset/vote_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/vote_icon.imageset/vote_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/voted_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "voted_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/voted_icon.imageset/voted_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/voted_icon.imageset/voted_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/watch_blue_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "watch_blue_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/Topic/watch_blue_icon.imageset/watch_blue_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/Topic/watch_blue_icon.imageset/watch_blue_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/blog_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "blog_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/blog_icon.imageset/blog_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/blog_icon.imageset/blog_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/edit_profile_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "edit_profile_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/edit_profile_icon.imageset/edit_profile_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/edit_profile_icon.imageset/edit_profile_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/github_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "github_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/github_icon.imageset/github_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/github_icon.imageset/github_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/local_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "local_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/local_icon.imageset/local_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/local_icon.imageset/local_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/tick_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tick_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/tick_icon.imageset/tick_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/tick_icon.imageset/tick_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/twitter_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "twitter_icon.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/User/twitter_icon.imageset/twitter_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/User/twitter_icon.imageset/twitter_icon.png -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/ViewPager/pager_title_indicator.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "pager_title_indicator.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PHPHub/Images.xcassets/ViewPager/pager_title_indicator.imageset/pager_title_indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/Images.xcassets/ViewPager/pager_title_indicator.imageset/pager_title_indicator.png -------------------------------------------------------------------------------- /PHPHub/Models/AdModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // AdModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | #import "AdApi.h" 11 | 12 | @interface AdModel : BaseModel 13 | @property (nonatomic, strong) AdApi *api; 14 | - (id)getAdvertsLaunchScreen:(BaseResultBlock)block; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Models/AdModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // AdModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "AdModel.h" 10 | #import "LaunchScreenAdDBManager.h" 11 | #import "LaunchScreenAdEntity.h" 12 | 13 | @implementation AdModel 14 | 15 | - (instancetype)init { 16 | self = [super init]; 17 | if (self) { 18 | _api = [[AdApi alloc] init]; 19 | } 20 | return self; 21 | } 22 | 23 | - (id)getAdvertsLaunchScreen:(BaseResultBlock)block { 24 | BaseResultBlock callback = ^(NSDictionary *data, NSError *error) { 25 | if (!error) { 26 | NSArray *adEntities = [data objectForKey:@"entities"]; 27 | [self insertAdEntitiesToLocalDataBase:adEntities]; 28 | } 29 | if (block) block(data, error); 30 | }; 31 | 32 | return [_api getAdvertsLaunchScreen:callback]; 33 | } 34 | 35 | - (void)insertAdEntitiesToLocalDataBase:(NSArray *)adEntities { 36 | [LaunchScreenAdDBManager eraseLaunchScreenAdData]; 37 | 38 | if (adEntities.count > 0) { 39 | [[BaseDBManager sharedInstance].db beginTransaction]; 40 | for (int i = 0; i < adEntities.count; i++) { 41 | LaunchScreenAdEntity *entity = [adEntities objectAtIndex:i]; 42 | [LaunchScreenAdDBManager insertOnDuplicateUpdate:entity]; 43 | } 44 | [[BaseDBManager sharedInstance].db commit]; 45 | 46 | [self checkLaunchScreenAdImageHasCached:adEntities]; 47 | } 48 | } 49 | 50 | - (void)checkLaunchScreenAdImageHasCached:(NSArray *)adEntities { 51 | for (int i = 0; i < adEntities.count; i++) { 52 | LaunchScreenAdEntity *launchScreenAdEntity = [adEntities objectAtIndex:i]; 53 | NSString *screenImageUrl = IS_IPHONE_4_OR_LESS ? launchScreenAdEntity.smallImage : launchScreenAdEntity.bigImage; 54 | NSString *imageWidth = [NSString stringWithFormat:@"%.f", SCREEN_WIDTH * 2]; 55 | NSString *imageHeight = [NSString stringWithFormat:@"%.f", SCREEN_HEIGHT * 2]; 56 | NSURL *imageLink = [BaseHelper qiniuImageCenter:screenImageUrl withWidth:imageWidth withHeight:imageHeight]; 57 | BOOL imageIsCache = [SDWebImageManager.sharedManager cachedImageExistsForURL:imageLink]; 58 | if (!imageIsCache) { 59 | [[[UIImageView alloc] init] sd_setImageWithURL:imageLink]; 60 | } 61 | } 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /PHPHub/Models/CategoryModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/10/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | #import "CategoryApi.h" 11 | 12 | @interface CategoryModel : BaseModel 13 | @property (nonatomic, strong) CategoryApi *api; 14 | - (id)getAllTopicCategory:(BaseResultBlock)block; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Models/CategoryModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/10/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CategoryModel.h" 10 | 11 | @implementation CategoryModel 12 | 13 | - (instancetype)init { 14 | self = [super init]; 15 | if (self) { 16 | _api = [[CategoryApi alloc] init]; 17 | } 18 | return self; 19 | } 20 | 21 | - (id)getAllTopicCategory:(BaseResultBlock)block { 22 | return [_api getAllTopicCategory:block]; 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /PHPHub/Models/NotificationModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/13/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | #import "NotificationApi.h" 11 | 12 | @interface NotificationModel : BaseModel 13 | @property (nonatomic, strong) NotificationApi *api; 14 | - (id)getNotificationList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 15 | - (id)getUnreadNotificationCount:(BaseResultBlock)block; 16 | @end 17 | -------------------------------------------------------------------------------- /PHPHub/Models/NotificationModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/13/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "NotificationModel.h" 10 | 11 | @implementation NotificationModel 12 | - (instancetype)init { 13 | self = [super init]; 14 | if (self) { 15 | _api = [[NotificationApi alloc] init]; 16 | } 17 | return self; 18 | } 19 | 20 | - (id)getNotificationList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 21 | return [_api getNotificationList:block atPage:pageIndex]; 22 | } 23 | 24 | - (id)getUnreadNotificationCount:(BaseResultBlock)block { 25 | return [_api getUnreadNotificationCount:block]; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /PHPHub/Models/TopicModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | #import "TopicApi.h" 11 | 12 | @interface TopicModel : BaseModel 13 | @property TopicApi *api; 14 | - (id)getAllTopic:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 15 | - (id)getExcellentTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 16 | - (id)getNewestTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 17 | - (id)getHotsTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 18 | - (id)getNoReplyTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 19 | - (id)getJobTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 20 | - (id)getWiKiList:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 21 | - (id)getTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 22 | - (id)getVotedTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex; 23 | - (id)getTopicById:(NSInteger)topicId callback:(BaseResultBlock)block; 24 | - (id)addCommentToTopic:(CommentEntity *)comment withBlock:(BaseResultBlock)block; 25 | - (id)createTopic:(TopicEntity *)entity withBlock:(BaseResultBlock)block; 26 | - (id)voteUpTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block; 27 | - (id)voteDownTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block; 28 | @end -------------------------------------------------------------------------------- /PHPHub/Models/TopicModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "TopicModel.h" 10 | 11 | @implementation TopicModel 12 | 13 | - (instancetype)init { 14 | self = [super init]; 15 | if (self) { 16 | _api = [[TopicApi alloc] init]; 17 | } 18 | return self; 19 | } 20 | 21 | - (id)getAllTopic:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 22 | return [_api getAll:block atPage:pageIndex]; 23 | } 24 | 25 | - (id)getExcellentTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 26 | return [_api getExcellentTopicList:block atPage:pageIndex]; 27 | } 28 | 29 | - (id)getNewestTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 30 | return [_api getNewestTopicList:block atPage:pageIndex]; 31 | } 32 | 33 | - (id)getHotsTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 34 | return [_api getHotsTopicList:block atPage:pageIndex]; 35 | } 36 | 37 | - (id)getNoReplyTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 38 | return [_api getNoReplyTopicList:block atPage:pageIndex]; 39 | } 40 | 41 | - (id)getJobTopicList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 42 | return [_api getJobTopicList:block atPage:pageIndex]; 43 | } 44 | 45 | - (id)getWiKiList:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 46 | return [_api getWiKiList:block atPage:pageIndex]; 47 | } 48 | 49 | - (id)getTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 50 | return [_api getTopicListByUser:userId callback:block atPage:pageIndex]; 51 | } 52 | 53 | - (id)getVotedTopicListByUser:(NSInteger)userId callback:(BaseResultBlock)block atPage:(NSInteger)pageIndex { 54 | return [_api getVotedTopicListByUser:userId callback:block atPage:pageIndex]; 55 | } 56 | 57 | - (id)getTopicById:(NSInteger)topicId callback:(BaseResultBlock)block { 58 | return [_api getTopicById:topicId callback:block]; 59 | } 60 | 61 | - (id)addCommentToTopic:(CommentEntity *)comment withBlock:(BaseResultBlock)block { 62 | return [_api addCommentToTopic:comment withBlock:block]; 63 | } 64 | 65 | - (id)voteUpTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block { 66 | return [_api voteUpTopic:topicId withBlock:block]; 67 | } 68 | 69 | - (id)voteDownTopic:(NSNumber *)topicId withBlock:(BaseResultBlock)block { 70 | return [_api voteDownTopic:topicId withBlock:block]; 71 | } 72 | 73 | - (id)createTopic:(TopicEntity *)entity withBlock:(BaseResultBlock)block { 74 | return [_api createTopic:entity withBlock:block]; 75 | } 76 | @end 77 | -------------------------------------------------------------------------------- /PHPHub/Models/UserModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserModel.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseModel.h" 10 | #import "UserApi.h" 11 | #import "UserDBManager.h" 12 | 13 | @interface UserModel : BaseModel 14 | @property (nonatomic, strong) UserApi *api; 15 | - (id)getCurrentUserData:(BaseResultBlock)block; 16 | - (id)getUserById:(NSNumber *)userId callback:(BaseResultBlock)block; 17 | - (id)loginWithUserName:(NSString *)username loginToken:(NSString *)loginToken block:(BaseResultBlock)block; 18 | - (id)updateUserProfile:(UserEntity *)user withBlock:(BaseResultBlock)block; 19 | @end 20 | -------------------------------------------------------------------------------- /PHPHub/Models/UserModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserModel.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UserModel.h" 10 | #import "AccessTokenHandler.h" 11 | 12 | @implementation UserModel 13 | 14 | - (instancetype)init { 15 | self = [super init]; 16 | if (self) { 17 | _api = [[UserApi alloc] init]; 18 | } 19 | return self; 20 | } 21 | 22 | - (id)getCurrentUserData:(BaseResultBlock)block { 23 | BaseResultBlock callback =^ (NSDictionary *data, NSError *error) { 24 | if (data) { 25 | UserEntity *user = data[@"entity"]; 26 | if (user) { 27 | [GVUserDefaults standardUserDefaults].currentUserId = user.userId; 28 | [[CurrentUser Instance] saveUser:user]; 29 | } 30 | if (block) block(data, nil); 31 | } else { 32 | if (block) block(nil, error); 33 | } 34 | }; 35 | 36 | return [_api getCurrentUserData:callback]; 37 | } 38 | 39 | - (id)getUserById:(NSNumber *)userId callback:(BaseResultBlock)block { 40 | return [_api getUserById:userId callback:block]; 41 | } 42 | 43 | - (id)loginWithUserName:(NSString *)username loginToken:(NSString *)loginToken block:(BaseResultBlock)block { 44 | BaseResultBlock callback =^ (NSDictionary *data, NSError *error) { 45 | if (data) { 46 | [self completeLoginAction:data]; 47 | [self getCurrentUserData:^(NSDictionary *userdata, NSError *error) { 48 | if (block) block(data, nil); 49 | }]; 50 | } else { 51 | if (block) block(nil, error); 52 | } 53 | }; 54 | 55 | return [_api loginWithUserName:username loginToken:loginToken block:callback]; 56 | } 57 | 58 | - (void)completeLoginAction:(NSDictionary *)data { 59 | [AccessTokenHandler storeLoginTokenGrantAccessToken:data[@"access_token"]]; 60 | [[BaseApi loginTokenGrantInstance] setUpLoginTokenGrantRequest]; 61 | [[CurrentUser Instance] setupClientRequestState:nil]; 62 | } 63 | 64 | - (id)updateUserProfile:(UserEntity *)user withBlock:(BaseResultBlock)block { 65 | BaseResultBlock callback =^ (NSDictionary *data, NSError *error) { 66 | if (!error) { 67 | UserEntity *userEntity = data[@"entity"]; 68 | [[CurrentUser Instance] saveUser:userEntity]; 69 | if (block) block(data, nil); 70 | } else { 71 | if (block) block(nil, error); 72 | } 73 | }; 74 | return [_api updateUserProfile:user withBlock:callback]; 75 | } 76 | @end 77 | -------------------------------------------------------------------------------- /PHPHub/PHPHub-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PHPHub-Prefix.pch 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #if DEBUG 10 | #define IS_IN_DEVELOPMENT TRUE 11 | #else 12 | #define IS_IN_DEVELOPMENT FALSE 13 | #endif 14 | 15 | #import "BaseApi.h" 16 | #import "APIConstant.h" 17 | #import "SecretConstant.h" 18 | #import "UIConstant.h" 19 | #import "DebugConstant.h" 20 | #import "UIView+Additions.h" 21 | #import "BaseHelper.h" 22 | #import "UIImageView+WebCache.h" 23 | #import "MJRefresh.h" 24 | #import "PaginationEntity.h" 25 | #import "AFOAuth2Manager+Addtions.h" 26 | #import "GVUserDefaults+Properties.h" 27 | #import "CurrentUser.h" 28 | #import "NSString+Additions.h" 29 | #import "UIViewController+Custom.h" 30 | #import "JumpToOtherVCHandler.h" 31 | #import "SVProgressHUD.h" 32 | #import "AnalyticsHandler.h" 33 | 34 | #define DidTapStatusBar @"DidTapStatusBar" -------------------------------------------------------------------------------- /PHPHub/PushConfig.example.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | APS_FOR_PRODUCTION 6 | 0 7 | CHANNEL 8 | Apple App Store 9 | APP_KEY 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /PHPHub/Resources/Migrations.bundle/20151002095034729_create_users_table.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for users 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS "users"; 5 | CREATE TABLE "users" ( 6 | "id" integer not null primary key, 7 | "name" varchar not null, 8 | "avatar" varchar null, 9 | "github_url" varchar null, 10 | "topic_count" integer not null default '0', 11 | "reply_count" integer not null default '0', 12 | "twitter_account" varchar null, 13 | "personal_website" varchar null, 14 | "company" varchar null, 15 | "city" varchar null, 16 | "email" varchar null, 17 | "introduction" varchar null, 18 | "github_name" varchar null, 19 | "real_name" varchar null, 20 | "replies_web_view" varchar null, 21 | "created_at" datetime not null, 22 | "updated_at" datetime null 23 | ); -------------------------------------------------------------------------------- /PHPHub/Resources/Migrations.bundle/20151019093301120_create_launchScreenAds_table.sql: -------------------------------------------------------------------------------- 1 | -- ---------------------------- 2 | -- Table structure for launchScreenAds 3 | -- ---------------------------- 4 | DROP TABLE IF EXISTS "launchScreenAds"; 5 | CREATE TABLE "launchScreenAds" ( 6 | "id" integer not null primary key, 7 | "image_small" varchar not null, 8 | "image_large" varchar not null, 9 | "type" varchar null, 10 | "payload" varchar not null, 11 | "display_time" integer not null default '0', 12 | "start_at" datetime not null, 13 | "expires_at" datetime not null 14 | ); 15 | -- ---------------------------- 16 | -- Indexes structure for table launchScreenAds 17 | -- ---------------------------- 18 | CREATE INDEX launchScreenAds_expiresAt_index on "launchScreenAds" ("expires_at"); -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/Library/GAIEcommerceProduct.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIEcommerceProduct.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | * Class to construct product related information for a Google Analytics beacon. Use this class to 11 | * report information about products sold by merchants or impressions of products seen by users. 12 | * Instances of this class can be associated with both Product Actions and Product 13 | * Impression Lists. 14 | *
15 | * Typical usage: 16 | * 17 | * [tracker set:kGAIScreenName value:@"MyScreen"]; 18 | * GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; 19 | * GAIEcommerceProduct *product = [[GAIEcommerceProduct alloc] init]; 20 | * [product setId:@""PID-1234""]; 21 | * [product setName:@"Space Monkeys!"]; 22 | * [product setPrice:@100]; 23 | * [product setQuantity:@2]; 24 | * [builder addProductImpression:product impressionList:@"listName"]; 25 | * [tracker send:[builder build]]; 26 | * 27 | */ 28 | @interface GAIEcommerceProduct : NSObject 29 | 30 | /*! 31 | Sets the id that is used to identify a product in GA reports. 32 | */ 33 | - (GAIEcommerceProduct *)setId:(NSString *)productId; 34 | 35 | /*! 36 | Sets the name that is used to indentify the product in GA reports. 37 | */ 38 | - (GAIEcommerceProduct *)setName:(NSString *)productName; 39 | 40 | /*! 41 | Sets the brand associated with the product in GA reports. 42 | */ 43 | - (GAIEcommerceProduct *)setBrand:(NSString *)productBrand; 44 | 45 | /*! 46 | Sets the category associated with the product in GA reports. 47 | */ 48 | - (GAIEcommerceProduct *)setCategory:(NSString *)productCategory; 49 | 50 | /*! 51 | Sets the variant of the product. 52 | */ 53 | - (GAIEcommerceProduct *)setVariant:(NSString *)productVariant; 54 | 55 | /*! 56 | Sets the price of the product. 57 | */ 58 | - (GAIEcommerceProduct *)setPrice:(NSNumber *)productPrice; 59 | 60 | /*! 61 | Sets the quantity of the product. This field is usually not used with product impressions. 62 | */ 63 | - (GAIEcommerceProduct *)setQuantity:(NSNumber *)productQuantity; 64 | 65 | /*! 66 | Sets the coupon code associated with the product. This field is usually not used with product 67 | impressions. 68 | */ 69 | - (GAIEcommerceProduct *)setCouponCode:(NSString *)productCouponCode; 70 | 71 | /*! 72 | Sets the position of the product on the screen/product impression list, etc. 73 | */ 74 | - (GAIEcommerceProduct *)setPosition:(NSNumber *)productPosition; 75 | 76 | /*! 77 | Sets the custom dimension associated with this product. 78 | */ 79 | - (GAIEcommerceProduct *)setCustomDimension:(NSUInteger)index value:(NSString *)value; 80 | 81 | /*! 82 | Sets the custom metric associated with this product. 83 | */ 84 | - (GAIEcommerceProduct *)setCustomMetric:(NSUInteger)index value:(NSNumber *)value; 85 | 86 | /*! 87 | Builds an NSDictionary of fields stored in this instance suitable for a product action. The 88 | index parameter is the index of this product in the product action list. 89 |
90 | Normally, users will have no need to call this method. 91 | */ 92 | - (NSDictionary *)buildWithIndex:(NSUInteger)index; 93 | 94 | /*! 95 | Builds an NSDictionary of fields stored in this instance suitable for an impression list. The 96 | lIndex parameter is the index of the product impression list while the index parameter is the 97 | index of this product in that impression list. 98 |
99 | Normally, users will have no need to call this method. 100 | */ 101 | - (NSDictionary *)buildWithListIndex:(NSUInteger)lIndex index:(NSUInteger)index; 102 | @end 103 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/Library/GAIEcommercePromotion.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAIEcommercePromotion.h 3 | @abstract Google Analytics iOS SDK Hit Format Header 4 | @copyright Copyright 2014 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | * Class to construct promotion related fields for Google Analytics hits. The fields from this class 11 | * can be used to represent internal promotions that run within an app, such as banners, banner ads 12 | * etc. 13 | * 14 | * Typical usage: 15 | * 16 | * GAIDictionaryBuilder *builder = [GAIDictionaryBuilder createScreenView]; 17 | * GAIEcommercePromotion *promotion = [[GAIEcommercePromotion alloc] init]; 18 | * [promotion setId:@"PROMO-ID1234"]; 19 | * [promotion setName:@"Home screen banner"]; 20 | * [builder set:kGAIPromotionClick forKey:kGAIPromotionAction]; 21 | * [builder addPromotion:promotion]; 22 | * [tracker send:builder.build]]; 23 | * 24 | */ 25 | @interface GAIEcommercePromotion : NSObject 26 | 27 | /*! 28 | Sets the id that is used to identify a promotion in GA reports. 29 | */ 30 | - (GAIEcommercePromotion *)setId:(NSString *)pid; 31 | 32 | /*! 33 | Sets the name that is used to identify a promotion in GA reports. 34 | */ 35 | - (GAIEcommercePromotion *)setName:(NSString *)name; 36 | 37 | /*! 38 | Sets the name of the creative associated with the promotion. 39 | */ 40 | - (GAIEcommercePromotion *)setCreative:(NSString *)creative; 41 | 42 | /*! 43 | Sets the position of the promotion. 44 | */ 45 | - (GAIEcommercePromotion *)setPosition:(NSString *)position; 46 | 47 | /*! 48 | Builds an NSDictionary of fields stored in this instance. The index parameter is the 49 | index of this promotion in that promotion list. 50 |
51 | Normally, users will have no need to call this method. 52 | */ 53 | - (NSDictionary *)buildWithIndex:(NSUInteger)index; 54 | @end 55 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/Library/GAILogger.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAILogger.h 3 | @abstract Google Analytics iOS SDK Source 4 | @copyright Copyright 2011 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | typedef NS_ENUM(NSUInteger, GAILogLevel) { 10 | kGAILogLevelNone = 0, 11 | kGAILogLevelError = 1, 12 | kGAILogLevelWarning = 2, 13 | kGAILogLevelInfo = 3, 14 | kGAILogLevelVerbose = 4 15 | }; 16 | 17 | /*! 18 | Protocol to be used for logging debug and informational messages from the SDK. 19 | Implementations of this protocol can be provided to the |GAI| class, 20 | to be used as the logger by the SDK. See the |logger| property in GAI.h. 21 | */ 22 | @protocol GAILogger 23 | @required 24 | 25 | /*! 26 | Only messages of |logLevel| and below are logged. 27 | */ 28 | @property (nonatomic, assign) GAILogLevel logLevel; 29 | 30 | /*! 31 | Logs message with log level |kGAILogLevelVerbose|. 32 | */ 33 | - (void)verbose:(NSString *)message; 34 | 35 | /*! 36 | Logs message with log level |kGAILogLevelInfo|. 37 | */ 38 | - (void)info:(NSString *)message; 39 | 40 | /*! 41 | Logs message with log level |kGAILogLevelWarning|. 42 | */ 43 | - (void)warning:(NSString *)message; 44 | 45 | /*! 46 | Logs message with log level |kGAILogLevelError|. 47 | */ 48 | - (void)error:(NSString *)message; 49 | @end 50 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/Library/GAITrackedViewController.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAITrackedViewController.h 3 | @abstract Google Analytics for iOS Tracked View Controller Header 4 | @copyright Copyright 2012 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | #import 9 | 10 | @protocol GAITracker; 11 | 12 | /*! 13 | Extends UIViewController to generate Google Analytics screenview calls 14 | whenever the view appears; this is done by overriding the `viewDidAppear:` 15 | method. The screen name must be set for any tracking calls to be made. 16 | 17 | By default, this will use [GAI defaultTracker] for tracking calls, but one can 18 | override this by setting the tracker property. 19 | */ 20 | @interface GAITrackedViewController : UIViewController 21 | 22 | /*! 23 | The tracker on which view tracking calls are be made, or `nil`, in which case 24 | [GAI defaultTracker] will be used. 25 | */ 26 | @property(nonatomic, assign) id tracker; 27 | /*! 28 | The screen name, for purposes of Google Analytics tracking. If this is `nil`, 29 | no tracking calls will be made. 30 | */ 31 | @property(nonatomic, copy) NSString *screenName; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/Library/GAITracker.h: -------------------------------------------------------------------------------- 1 | /*! 2 | @header GAITracker.h 3 | @abstract Google Analytics iOS SDK Tracker Header 4 | @copyright Copyright 2013 Google Inc. All rights reserved. 5 | */ 6 | 7 | #import 8 | 9 | /*! 10 | Google Analytics tracking interface. Obtain instances of this interface from 11 | [GAI trackerWithTrackingId:] to track screens, events, transactions, timing, 12 | and exceptions. The implementation of this interface is thread-safe, and no 13 | calls are expected to block or take a long time. All network and disk activity 14 | will take place in the background. 15 | */ 16 | @protocol GAITracker 17 | 18 | /*! 19 | Name of this tracker. 20 | */ 21 | @property(nonatomic, readonly) NSString *name; 22 | 23 | /*! 24 | Allow collection of IDFA and related fields if set to true. Default is false. 25 | */ 26 | @property(nonatomic) BOOL allowIDFACollection; 27 | 28 | /*! 29 | Set a tracking parameter. 30 | 31 | @param parameterName The parameter name. 32 | 33 | @param value The value to set for the parameter. If this is nil, the 34 | value for the parameter will be cleared. 35 | */ 36 | - (void)set:(NSString *)parameterName 37 | value:(NSString *)value; 38 | 39 | /*! 40 | Get a tracking parameter. 41 | 42 | @param parameterName The parameter name. 43 | 44 | @returns The parameter value, or nil if no value for the given parameter is 45 | set. 46 | */ 47 | - (NSString *)get:(NSString *)parameterName; 48 | 49 | /*! 50 | Queue tracking information with the given parameter values. 51 | 52 | @param parameters A map from parameter names to parameter values which will be 53 | set just for this piece of tracking information, or nil for none. 54 | */ 55 | - (void)send:(NSDictionary *)parameters; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/GoogleAnalytics/libGoogleAnalyticsServices.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/ThirdParty/GoogleAnalytics/libGoogleAnalyticsServices.a -------------------------------------------------------------------------------- /PHPHub/ThirdParty/JPush/lib/libPushSDK-1.8.5.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Aufree/PHPHub-iOS/28af43bb3c12331561d51a9d1781cd61fbd8dfd0/PHPHub/ThirdParty/JPush/lib/libPushSDK-1.8.5.a -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TOWebViewController/TOActivityChrome.h: -------------------------------------------------------------------------------- 1 | // 2 | // TOActivityChrome.h 3 | // 4 | // Copyright 2013-2015 Timothy Oliver. All rights reserved. 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 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell 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 17 | // OR 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 LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 21 | // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | #import 24 | 25 | extern NSString *const TOActivityTypeChrome; 26 | 27 | @interface TOActivityChrome : UIActivity 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TOWebViewController/TOActivitySafari.h: -------------------------------------------------------------------------------- 1 | // 2 | // TOActivitySafari.h 3 | // 4 | // Copyright 2013-2015 Timothy Oliver. All rights reserved. 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 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell 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 17 | // OR 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 LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 21 | // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | #import 24 | 25 | extern NSString *const TOActivityTypeSafari; 26 | 27 | @interface TOActivitySafari : UIActivity 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TOWebViewController/UIImage+TOWebViewControllerIcons.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+TOWebViewControllerIcons.h 3 | // 4 | // Copyright 2013-2015 Timothy Oliver. All rights reserved. 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 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell 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 17 | // OR 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 LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 21 | // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | #import 24 | 25 | /* Keys for each of the theming properties */ 26 | extern const NSString *TOWebViewControllerButtonTintColor; 27 | extern const NSString *TOWebViewControllerButtonBevelOpacity; 28 | 29 | @interface UIImage (TOWebViewControllerIcons) 30 | 31 | /* Navigtion Buttons */ 32 | + (instancetype)TOWebViewControllerIcon_backButtonWithAttributes:(NSDictionary *)attributes; 33 | + (instancetype)TOWebViewControllerIcon_forwardButtonWithAttributes:(NSDictionary *)attributes; 34 | + (instancetype)TOWebViewControllerIcon_refreshButtonWithAttributes:(NSDictionary *)attributes; 35 | + (instancetype)TOWebViewControllerIcon_stopButtonWithAttributes:(NSDictionary *)attributes; 36 | + (instancetype)TOWebViewControllerIcon_actionButtonWithAttributes:(NSDictionary *)attributes; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TPKeyboardAvoiding/TPKeyboardAvoidingCollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TPKeyboardAvoidingCollectionView.h 3 | // TPKeyboardAvoiding 4 | // 5 | // Created by Michael Tyson on 30/09/2013. 6 | // Copyright 2015 A Tasty Pixel & The CocoaBots. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIScrollView+TPKeyboardAvoidingAdditions.h" 11 | 12 | @interface TPKeyboardAvoidingCollectionView : UICollectionView 13 | - (BOOL)focusNextTextField; 14 | - (void)scrollToActiveTextField; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TPKeyboardAvoidingScrollView.h 3 | // TPKeyboardAvoiding 4 | // 5 | // Created by Michael Tyson on 30/09/2013. 6 | // Copyright 2015 A Tasty Pixel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIScrollView+TPKeyboardAvoidingAdditions.h" 11 | 12 | @interface TPKeyboardAvoidingScrollView : UIScrollView 13 | - (void)contentSizeToFit; 14 | - (BOOL)focusNextTextField; 15 | - (void)scrollToActiveTextField; 16 | @end 17 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TPKeyboardAvoiding/TPKeyboardAvoidingScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TPKeyboardAvoidingScrollView.m 3 | // TPKeyboardAvoiding 4 | // 5 | // Created by Michael Tyson on 30/09/2013. 6 | // Copyright 2015 A Tasty Pixel. All rights reserved. 7 | // 8 | 9 | #import "TPKeyboardAvoidingScrollView.h" 10 | 11 | @interface TPKeyboardAvoidingScrollView () 12 | @end 13 | 14 | @implementation TPKeyboardAvoidingScrollView 15 | 16 | #pragma mark - Setup/Teardown 17 | 18 | - (void)setup { 19 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; 20 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TPKeyboardAvoiding_keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 21 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextViewTextDidBeginEditingNotification object:nil]; 22 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToActiveTextField) name:UITextFieldTextDidBeginEditingNotification object:nil]; 23 | } 24 | 25 | -(id)initWithFrame:(CGRect)frame { 26 | if ( !(self = [super initWithFrame:frame]) ) return nil; 27 | [self setup]; 28 | return self; 29 | } 30 | 31 | -(void)awakeFromNib { 32 | [super awakeFromNib]; 33 | [self setup]; 34 | } 35 | 36 | -(void)dealloc { 37 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 38 | #if !__has_feature(objc_arc) 39 | [super dealloc]; 40 | #endif 41 | } 42 | 43 | -(void)setFrame:(CGRect)frame { 44 | [super setFrame:frame]; 45 | [self TPKeyboardAvoiding_updateContentInset]; 46 | } 47 | 48 | -(void)setContentSize:(CGSize)contentSize { 49 | [super setContentSize:contentSize]; 50 | [self TPKeyboardAvoiding_updateFromContentSizeChange]; 51 | } 52 | 53 | - (void)contentSizeToFit { 54 | self.contentSize = [self TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames]; 55 | } 56 | 57 | - (BOOL)focusNextTextField { 58 | return [self TPKeyboardAvoiding_focusNextTextField]; 59 | 60 | } 61 | - (void)scrollToActiveTextField { 62 | return [self TPKeyboardAvoiding_scrollToActiveTextField]; 63 | } 64 | 65 | #pragma mark - Responders, events 66 | 67 | -(void)willMoveToSuperview:(UIView *)newSuperview { 68 | [super willMoveToSuperview:newSuperview]; 69 | if ( !newSuperview ) { 70 | [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; 71 | } 72 | } 73 | 74 | - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 75 | [[self TPKeyboardAvoiding_findFirstResponderBeneathView:self] resignFirstResponder]; 76 | [super touchesEnded:touches withEvent:event]; 77 | } 78 | 79 | -(BOOL)textFieldShouldReturn:(UITextField *)textField { 80 | if ( ![self focusNextTextField] ) { 81 | [textField resignFirstResponder]; 82 | } 83 | return YES; 84 | } 85 | 86 | -(void)layoutSubviews { 87 | [super layoutSubviews]; 88 | [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) object:self]; 89 | [self performSelector:@selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:) withObject:self afterDelay:0.1]; 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TPKeyboardAvoiding/TPKeyboardAvoidingTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TPKeyboardAvoidingTableView.h 3 | // TPKeyboardAvoiding 4 | // 5 | // Created by Michael Tyson on 30/09/2013. 6 | // Copyright 2015 A Tasty Pixel. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIScrollView+TPKeyboardAvoidingAdditions.h" 11 | 12 | @interface TPKeyboardAvoidingTableView : UITableView 13 | - (BOOL)focusNextTextField; 14 | - (void)scrollToActiveTextField; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TPKeyboardAvoiding/UIScrollView+TPKeyboardAvoidingAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIScrollView+TPKeyboardAvoidingAdditions.h 3 | // TPKeyboardAvoiding 4 | // 5 | // Created by Michael Tyson on 30/09/2013. 6 | // Copyright 2015 A Tasty Pixel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIScrollView (TPKeyboardAvoidingAdditions) 12 | - (BOOL)TPKeyboardAvoiding_focusNextTextField; 13 | - (void)TPKeyboardAvoiding_scrollToActiveTextField; 14 | 15 | - (void)TPKeyboardAvoiding_keyboardWillShow:(NSNotification*)notification; 16 | - (void)TPKeyboardAvoiding_keyboardWillHide:(NSNotification*)notification; 17 | - (void)TPKeyboardAvoiding_updateContentInset; 18 | - (void)TPKeyboardAvoiding_updateFromContentSizeChange; 19 | - (void)TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView:(UIView*)view; 20 | - (UIView*)TPKeyboardAvoiding_findFirstResponderBeneathView:(UIView*)view; 21 | -(CGSize)TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames; 22 | @end 23 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/TitlePagerView/TitlePagerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TitlePagerView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol TitlePagerViewDelegate 12 | @optional 13 | - (void)didTouchBWTitle:(NSUInteger)index; 14 | @end 15 | 16 | @interface TitlePagerView : UIView 17 | 18 | @property (nonatomic, strong) UIFont *font; 19 | @property (nonatomic, weak) id delegate; 20 | 21 | - (void)addObjects:(NSArray *)images; 22 | - (void)adjustTitleViewByIndex:(CGFloat)index; 23 | + (CGFloat)calculateTitleWidth:(NSArray *)titleArray withFont:(UIFont *)titleFont; 24 | - (void)updatePageIndicatorPosition:(CGFloat)xPosition; 25 | @end 26 | -------------------------------------------------------------------------------- /PHPHub/ThirdParty/ViewPagerController/ViewPagerController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewPagerController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, ViewPagerOption) { 12 | ViewPagerOptionTabHeight, 13 | ViewPagerOptionTabOffset, 14 | ViewPagerOptionTabWidth, 15 | ViewPagerOptionTabLocation, 16 | ViewPagerOptionStartFromSecondTab, 17 | ViewPagerOptionCenterCurrentTab 18 | }; 19 | 20 | typedef NS_ENUM(NSUInteger, ViewPagerComponent) { 21 | ViewPagerIndicator, 22 | ViewPagerTabsView, 23 | ViewPagerContent 24 | }; 25 | 26 | @protocol ViewPagerDataSource; 27 | @protocol ViewPagerDelegate; 28 | 29 | @interface ViewPagerController : UIViewController 30 | 31 | @property (nonatomic, weak) id dataSource; 32 | @property (nonatomic, weak) id delegate; 33 | 34 | @property UIPageViewController *pageViewController; 35 | 36 | - (UIViewController *)viewControllerAtIndex:(NSUInteger)index; 37 | 38 | #pragma mark ViewPagerOptions 39 | 40 | // 1.0: YES, 0.0: NO, defines if view should appear with the second or the first tab 41 | // Defaults to NO 42 | @property CGFloat startFromSecondTab; 43 | 44 | // 1.0: YES, 0.0: NO, defines if tabs should be centered, with the given tabWidth 45 | // Defaults to NO 46 | @property CGFloat centerCurrentTab; 47 | 48 | #pragma mark Colors 49 | @property UIColor *contentViewBackgroundColor; 50 | 51 | @property (nonatomic) BOOL manualLoadData; 52 | @property (nonatomic) BOOL scrollingLocked; 53 | #pragma mark Methods 54 | // Reload all tabs and contents 55 | - (void)reloadData; 56 | 57 | @end 58 | 59 | #pragma mark dataSource 60 | @protocol ViewPagerDataSource 61 | 62 | // Asks dataSource how many tabs will be 63 | - (NSUInteger)numberOfTabsForViewPager:(ViewPagerController *)viewPager; 64 | 65 | @optional 66 | // The content for any tab. Return a view controller and ViewPager will use its view to show as content 67 | - (UIViewController *)viewPager:(ViewPagerController *)viewPager contentViewControllerForTabAtIndex:(NSUInteger)index; 68 | - (UIView *)viewPager:(ViewPagerController *)viewPager contentViewForTabAtIndex:(NSUInteger)index; 69 | 70 | @end 71 | 72 | #pragma mark delegate 73 | @protocol ViewPagerDelegate 74 | 75 | @optional 76 | // delegate object must implement this method if wants to be informed when a tab changes 77 | - (void)viewPager:(ViewPagerController *)viewPager didChangeTabToIndex:(NSUInteger)index; 78 | // Every time - reloadData called, ViewPager will ask its delegate for option values 79 | // So you don't have to set options from ViewPager itself 80 | - (CGFloat)viewPager:(ViewPagerController *)viewPager valueForOption:(ViewPagerOption)option withDefault:(CGFloat)value; 81 | 82 | - (void)setSubViewScrollStatus:(BOOL)enabled; 83 | @end -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/AFOAuth2Manager/AFOAuth2Manager+Addtions.h: -------------------------------------------------------------------------------- 1 | // 2 | // AFOAuth2Manager+Addtions.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "AFOAuth2Manager.h" 10 | 11 | @interface AFOAuth2Manager (Addtions) 12 | - (AFHTTPRequestOperation *)authenticateUsingOAuthWithURLString:(NSString *)URLString 13 | username:(NSString *)username 14 | loginToken:(NSString *)loginToken 15 | scope:(NSString *)scope 16 | success:(void (^)(AFOAuthCredential *credential))success 17 | failure:(void (^)(NSError *error))failure; 18 | @end 19 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/AFOAuth2Manager/AFOAuth2Manager+Addtions.m: -------------------------------------------------------------------------------- 1 | // 2 | // AFOAuth2Manager+Addtions.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | NSString * const kAFOAuthLoginTokenCredentialsGrantType = @"login_token"; 10 | 11 | #import "AFOAuth2Manager+Addtions.h" 12 | 13 | @implementation AFOAuth2Manager (Addtions) 14 | - (AFHTTPRequestOperation *)authenticateUsingOAuthWithURLString:(NSString *)URLString 15 | username:(NSString *)username 16 | loginToken:(NSString *)loginToken 17 | scope:(NSString *)scope 18 | success:(void (^)(AFOAuthCredential *credential))success 19 | failure:(void (^)(NSError *error))failure { 20 | NSParameterAssert(username); 21 | NSParameterAssert(scope); 22 | 23 | NSDictionary *parameters = @{ 24 | @"grant_type": kAFOAuthLoginTokenCredentialsGrantType, 25 | @"username": username, 26 | @"login_token": loginToken, 27 | @"scope": scope 28 | }; 29 | 30 | return [self authenticateUsingOAuthWithURLString:URLString parameters:parameters success:success failure:failure]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/GVUserDefaults/GVUserDefaults+Properties.h: -------------------------------------------------------------------------------- 1 | // 2 | // GVUserDefaults+Properties.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "GVUserDefaults.h" 10 | 11 | @interface GVUserDefaults (Properties) 12 | @property (nonatomic, copy) NSString *userClientToken; 13 | @property (nonatomic, copy) NSNumber *currentUserId; 14 | @property (nonatomic, strong) NSDate *lastTimeShowLaunchScreenAd; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/GVUserDefaults/GVUserDefaults+Properties.m: -------------------------------------------------------------------------------- 1 | // 2 | // GVUserDefaults+Properties.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/30/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "GVUserDefaults+Properties.h" 10 | 11 | @implementation GVUserDefaults (Properties) 12 | @dynamic userClientToken; 13 | @dynamic currentUserId; 14 | @dynamic lastTimeShowLaunchScreenAd; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/NSString/NSString+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Additions.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/1/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Additions) 12 | + (BOOL)isStringEmpty:(NSString *)string; 13 | + (NSNumber *)covertToNumber:(NSString *)numberString; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/NSString/NSString+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Additions.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/1/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "NSString+Additions.h" 10 | 11 | @implementation NSString (Additions) 12 | + (BOOL)isStringEmpty:(NSString *)string { 13 | if([string length] == 0) { //string is empty or nil 14 | return YES; 15 | } 16 | 17 | if(![[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) { 18 | //string is all whitespace 19 | return YES; 20 | } 21 | 22 | return NO; 23 | } 24 | 25 | + (NSNumber *)covertToNumber:(NSString *)numberString { 26 | NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 27 | formatter.numberStyle = NSNumberFormatterDecimalStyle; 28 | return [formatter numberFromString:numberString]; 29 | } 30 | @end 31 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/NSURL+QueryDictionary/NSURL+QueryDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Query.h 3 | // NSURL+Query 4 | // 5 | // Created by Jon Crooke on 10/12/2013. 6 | // Copyright (c) 2013 Jonathan Crooke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSURL (UQ_URLQuery) 12 | 13 | /** 14 | * @return URL's query component as keys/values 15 | * Returns nil for an empty query 16 | */ 17 | - (NSDictionary*) uq_queryDictionary; 18 | 19 | /** 20 | * @return URL with keys values appending to query string 21 | * @param queryDictionary Query keys/values 22 | * @param sortedKeys Sorted the keys alphabetically? 23 | * @warning If keys overlap in receiver and query dictionary, 24 | * behaviour is undefined. 25 | */ 26 | - (NSURL*) uq_URLByAppendingQueryDictionary:(NSDictionary*) queryDictionary 27 | withSortedKeys:(BOOL) sortedKeys; 28 | 29 | /** As above, but `sortedKeys=NO` */ 30 | - (NSURL*) uq_URLByAppendingQueryDictionary:(NSDictionary*) queryDictionary; 31 | 32 | /** 33 | * @return Copy of URL with its query component replaced with 34 | * the specified dictionary. 35 | * @param queryDictionary A new query dictionary 36 | * @param sortedKeys Whether or not to sort the query keys 37 | */ 38 | - (NSURL*) uq_URLByReplacingQueryWithDictionary:(NSDictionary*) queryDictionary 39 | withSortedKeys:(BOOL) sortedKeys; 40 | 41 | /** As above, but `sortedKeys=NO` */ 42 | - (NSURL*) uq_URLByReplacingQueryWithDictionary:(NSDictionary*) queryDictionary; 43 | 44 | /** @return Receiver with query component completely removed */ 45 | - (NSURL*) uq_URLByRemovingQuery; 46 | 47 | @end 48 | 49 | #pragma mark - 50 | 51 | @interface NSString (UQ_URLQuery) 52 | 53 | /** 54 | * @return If the receiver is a valid URL query component, returns 55 | * components as key/value pairs. If couldn't split into *any* pairs, 56 | * returns nil. 57 | */ 58 | - (NSDictionary*) uq_URLQueryDictionary; 59 | 60 | @end 61 | 62 | #pragma mark - 63 | 64 | @interface NSDictionary (UQ_URLQuery) 65 | 66 | /** 67 | * @return URL query string component created from the keys and values in 68 | * the dictionary. Returns nil for an empty dictionary. 69 | * @param sortedKeys Sorted the keys alphabetically? 70 | * @see cavetas from the main `NSURL` category as well. 71 | */ 72 | - (NSString*) uq_URLQueryStringWithSortedKeys:(BOOL) sortedKeys; 73 | 74 | /** As above, but `sortedKeys=NO` */ 75 | - (NSString*) uq_URLQueryString; 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/UIResponder/UIResponder+Router.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+Router.h 3 | // PHPHub 4 | // 5 | // Created by zhengjinghua on 9/24/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIResponder (Router) 12 | 13 | - (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/UIResponder/UIResponder+Router.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIResponder+Router.m 3 | // PHPHub 4 | // 5 | // Created by zhengjinghua on 9/24/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UIResponder+Router.h" 10 | 11 | @implementation UIResponder (Router) 12 | 13 | - (void)routerEventWithName:(NSString *)eventName userInfo:(NSDictionary *)userInfo { 14 | [[self nextResponder] routerEventWithName:eventName userInfo:userInfo]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/UIView/UIView+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Additions.h 3 | // 4 | // Created by Jin on 15/3/25. 5 | // Copyright (c) 2015年 Jin. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @interface UIView (Additions) 11 | 12 | - (id) initWithParent:(UIView *)parent; 13 | + (id) viewWithParent:(UIView *)parent; 14 | - (void)removeAllSubViews; 15 | - (UIViewController*)viewController; 16 | 17 | 18 | // Position of the top-left corner in superview's coordinates 19 | @property CGPoint position; 20 | @property CGFloat x; 21 | @property CGFloat y; 22 | @property CGFloat top; 23 | @property CGFloat bottom; 24 | @property CGFloat left; 25 | @property CGFloat right; 26 | 27 | 28 | // makes hiding more logical 29 | @property BOOL visible; 30 | 31 | 32 | // Setting size keeps the position (top-left corner) constant 33 | @property CGSize size; 34 | @property CGFloat width; 35 | @property CGFloat height; 36 | 37 | @end 38 | 39 | @interface UIImageView (MFAdditions) 40 | 41 | - (void) setImageWithName:(NSString *)name; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/UIViewController/UIViewController+Custom.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Custom.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/3/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (Custom) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Utils/Categories/UIViewController/UIViewController+Custom.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Custom.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/3/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+Custom.h" 10 | 11 | @implementation UIViewController (Custom) 12 | 13 | + (void)load { 14 | 15 | Method viewWillAppear = class_getInstanceMethod(self, @selector(customViewWillAppear:)); 16 | 17 | Method customViewWillAppear = class_getInstanceMethod(self, @selector(viewWillAppear:)); 18 | method_exchangeImplementations(viewWillAppear, customViewWillAppear); 19 | } 20 | 21 | - (void)customViewWillAppear:(BOOL)animated { 22 | [self customViewWillAppear:animated]; 23 | [self analyticsScreenView]; 24 | 25 | BOOL modalPresent = (BOOL)(self.presentingViewController); 26 | 27 | if (modalPresent) { 28 | [self createCancelButton]; 29 | return; 30 | } 31 | 32 | if ([self.navigationController.viewControllers indexOfObject:self] != 0 && !self.navigationItem.hidesBackButton) { 33 | [self createBackButton]; 34 | } 35 | } 36 | 37 | - (void)analyticsScreenView { 38 | NSString *title = self.navigationItem.title; 39 | if (title) { 40 | [AnalyticsHandler logScreen:title]; 41 | } 42 | } 43 | 44 | - (void)createBackButton { 45 | UIImage *backImage = [UIImage imageNamed:@"back"]; 46 | UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:backImage 47 | style:UIBarButtonItemStylePlain 48 | target:self 49 | action:@selector(closeView)]; 50 | self.navigationItem.leftBarButtonItem = backButton; 51 | self.navigationController.interactivePopGestureRecognizer.delegate = (id)self; 52 | self.navigationItem.backBarButtonItem = nil; 53 | } 54 | 55 | - (void)createCancelButton { 56 | UIBarButtonItem *cancelBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"cancel"] 57 | style:UIBarButtonItemStylePlain 58 | target:self 59 | action:@selector(closeView)]; 60 | cancelBarButtonItem.tintColor = [UIColor colorWithRed:0.502 green:0.776 blue:0.200 alpha:1.000]; 61 | self.navigationItem.leftBarButtonItem = cancelBarButtonItem; 62 | } 63 | 64 | - (void)closeView { 65 | BOOL modalPresent = (BOOL)(self.presentingViewController); 66 | if (modalPresent) { 67 | [self.navigationController dismissViewControllerAnimated:YES completion:nil]; 68 | } else { 69 | [self.navigationController popViewControllerAnimated:YES]; 70 | } 71 | } 72 | @end 73 | -------------------------------------------------------------------------------- /PHPHub/Utils/DBManager/LaunchScreenAdDBManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdDBManager.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseDBManager.h" 10 | 11 | @interface LaunchScreenAdDBManager : BaseDBManager 12 | + (id)findLaunchScreenAdByExpries; 13 | + (id)getLaunchScreenAdByExpriesInLocal; 14 | + (id)eraseLaunchScreenAdData; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Utils/DBManager/LaunchScreenAdDBManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdDBManager.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "LaunchScreenAdDBManager.h" 10 | #import "LaunchScreenAdEntity.h" 11 | 12 | @implementation LaunchScreenAdDBManager 13 | 14 | + (id)findLaunchScreenAdByExpries { 15 | LaunchScreenAdEntity *entity = [self getLaunchScreenAdByExpriesInLocal]; 16 | 17 | if (entity) { 18 | return entity; 19 | } 20 | 21 | return nil; 22 | } 23 | 24 | + (id)getLaunchScreenAdByExpriesInLocal { 25 | NSError *error = nil; 26 | MTLModel *model = [[LaunchScreenAdEntity alloc] init]; 27 | NSString *query = [NSString stringWithFormat:@"select * from %@ where expires_at > datetime(CURRENT_TIMESTAMP,'localtime') order by datetime(expires_at) asc limit 1", [model.class FMDBTableName]]; 28 | NSArray *params = [MTLFMDBAdapter primaryKeysValues:model]; 29 | FMResultSet *resultSet = [[BaseDBManager sharedInstance].db executeQuery:query withArgumentsInArray:params]; 30 | if ([resultSet next]) { 31 | return [MTLFMDBAdapter modelOfClass:model.class fromFMResultSet:resultSet error:&error]; 32 | } 33 | return nil; 34 | } 35 | 36 | + (id)eraseLaunchScreenAdData { 37 | NSError *error = nil; 38 | MTLModel *model = [[LaunchScreenAdEntity alloc] init]; 39 | NSString *query = [NSString stringWithFormat:@"DELETE FROM %@", [model.class FMDBTableName]]; 40 | NSArray *params = [MTLFMDBAdapter primaryKeysValues:model]; 41 | FMResultSet *resultSet = [[BaseDBManager sharedInstance].db executeQuery:query withArgumentsInArray:params]; 42 | if ([resultSet next]) { 43 | return [MTLFMDBAdapter modelOfClass:model.class fromFMResultSet:resultSet error:&error]; 44 | } 45 | return nil; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /PHPHub/Utils/DBManager/UserDBManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserDBManager.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/2/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseDBManager.h" 10 | #import "UserEntity.h" 11 | 12 | @interface UserDBManager : BaseDBManager 13 | + (UserEntity *)findByUserId:(NSNumber *)userId; 14 | @end -------------------------------------------------------------------------------- /PHPHub/Utils/DBManager/UserDBManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserDBManager.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/2/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UserDBManager.h" 10 | 11 | @implementation UserDBManager 12 | 13 | + (UserEntity *)findByUserId:(NSNumber *)userId { 14 | UserEntity *tmpEntity = [[UserEntity alloc] init]; 15 | tmpEntity.userId = userId; 16 | return [UserDBManager findUsingPrimaryKeys:tmpEntity]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/CategoryEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/23/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | @interface CategoryEntity : BaseEntity 12 | @property (nonatomic, strong) NSNumber *categoryId; 13 | @property (nonatomic, copy) NSString *categoryName; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/CategoryEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/23/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CategoryEntity.h" 10 | 11 | @implementation CategoryEntity 12 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 13 | return @{ 14 | @"categoryId" : @"id", 15 | @"categoryName" : @"name", 16 | }; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/CommentEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommentEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | @interface CommentEntity : BaseEntity 12 | @property (nonatomic, copy) NSNumber *commentId; 13 | @property (nonatomic, copy) NSNumber *topicId; 14 | @property (nonatomic, copy) NSNumber *userId; 15 | @property (nonatomic, copy) NSString *commentBody; 16 | @end 17 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/CommentEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // CommentEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CommentEntity.h" 10 | 11 | 12 | @implementation CommentEntity 13 | 14 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 15 | return @{ 16 | @"commentId" : @"id", 17 | @"topicId" : @"topic_id", 18 | @"userId" : @"user_id", 19 | @"commentBody" : @"body", 20 | }; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/LaunchScreenAdEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | typedef NS_ENUM(NSInteger, LaunchScreenType) { 12 | LaunchScreenTypeByTopic = 0, 13 | LaunchScreenTypeByUser = 1, 14 | LaunchScreenTypeByWeb = 2, 15 | LaunchScreenTypeUnknow = 3, 16 | }; 17 | 18 | @interface LaunchScreenAdEntity : BaseEntity 19 | @property (nonatomic, copy) NSNumber *launchScreenAdId; 20 | @property (nonatomic, copy) NSString *launchDescription; 21 | @property (nonatomic, copy) NSString *smallImage; 22 | @property (nonatomic, copy) NSString *bigImage; 23 | @property (nonatomic, assign) LaunchScreenType type; 24 | @property (nonatomic, strong) NSString *launchScreenType; 25 | @property (nonatomic, copy) NSString *payload; 26 | @property (nonatomic, strong) NSDate *startAt; 27 | @property (nonatomic, strong) NSDate *expiresAt; 28 | @property (nonatomic, copy) NSNumber *displayTime; 29 | @end 30 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/LaunchScreenAdEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "LaunchScreenAdEntity.h" 10 | 11 | @implementation LaunchScreenAdEntity 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return @{ 15 | @"launchScreenAdId" : @"id", 16 | @"launchDescription" : @"description", 17 | @"smallImage" : @"image_small", 18 | @"bigImage" : @"image_large", 19 | @"launchScreenType" : @"type", 20 | @"payload" : @"payload", 21 | @"displayTime" : @"display_time", 22 | @"startAt" : @"start_at", 23 | @"expiresAt" : @"expires_at", 24 | }; 25 | } 26 | 27 | #pragma mark - MTLFMDBAdapter Stuff 28 | 29 | + (NSDictionary *)FMDBColumnsByPropertyKey { 30 | return @{ 31 | @"launchScreenAdId" : @"id", 32 | @"launchDescription" : [NSNull null], 33 | @"smallImage" : @"image_small", 34 | @"bigImage" : @"image_large", 35 | @"launchScreenType" : @"type", 36 | @"payload" : @"payload", 37 | @"displayTime" : @"display_time", 38 | @"startAt" : @"start_at", 39 | @"expiresAt" : @"expires_at", 40 | @"type" : [NSNull null] 41 | }; 42 | } 43 | 44 | - (LaunchScreenType)type { 45 | if (!_type) { 46 | if ([self.launchScreenType isEqualToString:@"topic"]) { 47 | _type = LaunchScreenTypeByTopic; 48 | } else if ([self.launchScreenType isEqualToString:@"user"]) { 49 | _type = LaunchScreenTypeByUser; 50 | } else if ([self.launchScreenType isEqualToString:@"web"]) { 51 | _type = LaunchScreenTypeByWeb; 52 | } else { 53 | _type = LaunchScreenTypeUnknow; 54 | } 55 | } 56 | return _type; 57 | } 58 | 59 | + (NSArray *)FMDBPrimaryKeys { 60 | return @[@"id"]; 61 | } 62 | 63 | + (NSString *)FMDBTableName { 64 | return @"launchScreenAds"; 65 | } 66 | @end 67 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/NotificationEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | #import "UserEntity.h" 11 | 12 | @interface NotificationEntity : BaseEntity 13 | @property (nonatomic, strong) NSNumber *notificationId; 14 | @property (nonatomic, copy) NSString *message; 15 | @property (nonatomic, strong) UserEntity *fromUser; 16 | @property (nonatomic, strong) TopicEntity *topic; 17 | @property (nonatomic, strong) NSDate *createdAt; 18 | @end 19 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/NotificationEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "NotificationEntity.h" 10 | 11 | @implementation NotificationEntity 12 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 13 | return @{ 14 | @"notificationId" : @"id", 15 | @"message" : @"message", 16 | @"fromUser" : @"from_user.data", 17 | @"topic" : @"topic.data", 18 | @"createdAt" : @"created_at", 19 | }; 20 | } 21 | 22 | + (NSValueTransformer *)fromUserJSONTransformer { 23 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[UserEntity class]]; 24 | } 25 | 26 | + (NSValueTransformer *)topicJSONTransformer { 27 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[TopicEntity class]]; 28 | } 29 | @end -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/PaginationEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // PaginationEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | @interface PaginationEntity : BaseEntity 12 | @property (nonatomic, assign) NSUInteger totalPages; 13 | @property (nonatomic, assign) NSUInteger currentPage; 14 | @property (nonatomic, assign) NSUInteger perPage; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/PaginationEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // PaginationEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "PaginationEntity.h" 10 | 11 | @implementation PaginationEntity 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return @{ 15 | @"totalPages" : @"total_pages", 16 | @"currentPage" : @"current_page", 17 | @"perPage" : @"per_page" 18 | }; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/TopicEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | #import "UserEntity.h" 11 | #import "CategoryEntity.h" 12 | 13 | @interface TopicEntity : BaseEntity 14 | @property (nonatomic, strong) NSNumber *topicId; 15 | @property (nonatomic, strong) NSNumber *categoryId; 16 | @property (nonatomic, copy) NSString *topicTitle; 17 | @property (nonatomic, copy) NSString *topicBody; 18 | @property (nonatomic, strong) NSNumber *topicRepliesCount; 19 | @property (nonatomic, strong) NSNumber *voteCount; 20 | @property (nonatomic, strong) UserEntity *user; 21 | @property (nonatomic, strong) UserEntity *lastReplyUser; 22 | @property (nonatomic, strong) CategoryEntity *category; 23 | @property (nonatomic, copy) NSString *topicContentUrl; 24 | @property (nonatomic, copy) NSString *topicRepliesUrl; 25 | @property (nonatomic, assign) BOOL voteUp; 26 | @property (nonatomic, assign) BOOL voteDown; 27 | @property (nonatomic, strong) NSDate *updatedAt; 28 | @end 29 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/TopicEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "TopicEntity.h" 10 | 11 | @implementation TopicEntity 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return @{ 15 | @"topicId" : @"id", 16 | @"categoryId" : @"category_id", 17 | @"topicTitle" : @"title", 18 | @"topicBody" : @"body", 19 | @"topicRepliesCount" : @"reply_count", 20 | @"voteCount" : @"vote_count", 21 | @"user" : @"user.data", 22 | @"lastReplyUser" : @"last_reply_user.data", 23 | @"category" : @"category.data", 24 | @"topicContentUrl" : @"links.details_web_view", 25 | @"topicRepliesUrl" : @"links.replies_web_view", 26 | @"voteUp" : @"vote_up", 27 | @"voteDown" : @"vote_down", 28 | @"updatedAt" : @"updated_at", 29 | }; 30 | } 31 | 32 | + (NSValueTransformer *)userJSONTransformer { 33 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[UserEntity class]]; 34 | } 35 | 36 | + (NSValueTransformer *)lastReplyUserJSONTransformer { 37 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[UserEntity class]]; 38 | } 39 | 40 | + (NSValueTransformer *)categoryJSONTransformer { 41 | return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:[CategoryEntity class]]; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/UserEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserEntity.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseEntity.h" 10 | 11 | @interface UserEntity : BaseEntity 12 | @property (nonatomic, copy) NSNumber *userId; 13 | @property (nonatomic, copy) NSString *githubURL; 14 | @property (nonatomic, copy) NSString *username; 15 | @property (nonatomic, copy) NSString *avatar; 16 | @property (nonatomic, copy) NSNumber *topicCount; 17 | @property (nonatomic, copy) NSNumber *replyCount; 18 | @property (nonatomic, copy) NSNumber *notificationCount; 19 | @property (nonatomic, copy) NSString *twitterAccount; 20 | @property (nonatomic, copy) NSString *blogURL; 21 | @property (nonatomic, copy) NSString *company; 22 | @property (nonatomic, copy) NSString *city; 23 | @property (nonatomic, copy) NSString *email; 24 | @property (nonatomic, copy) NSString *introduction; 25 | @property (nonatomic, copy) NSString *githubName; 26 | @property (nonatomic, copy) NSString *realName; 27 | @property (nonatomic, copy) NSString *repliesUrl; 28 | @property (nonatomic, strong) NSDate *createdAtDate; 29 | @property (nonatomic, strong) NSDate *updatedAtDate; 30 | @end 31 | -------------------------------------------------------------------------------- /PHPHub/Utils/Entities/UserEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserEntity.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "UserEntity.h" 10 | 11 | @implementation UserEntity 12 | 13 | + (NSDictionary *)JSONKeyPathsByPropertyKey { 14 | return @{ 15 | @"userId" : @"id", 16 | @"username" : @"name", 17 | @"avatar" : @"avatar", 18 | @"topicCount" : @"topic_count", 19 | @"replyCount" : @"reply_count", 20 | @"notificationCount" : @"notification_count", 21 | @"twitterAccount" : @"twitter_account", 22 | @"company" : @"company", 23 | @"city" : @"city", 24 | @"email" : @"email", 25 | @"introduction" : @"introduction", 26 | @"githubName" : @"github_name", 27 | @"githubURL" : @"github_url", 28 | @"realName" : @"real_name", 29 | @"blogURL" : @"personal_website", 30 | @"repliesUrl" : @"links.replies_web_view", 31 | @"createdAtDate" : @"created_at", 32 | @"updatedAtDate" : @"updated_at", 33 | }; 34 | } 35 | 36 | + (NSArray *)FMDBPrimaryKeys { 37 | return @[@"id"]; 38 | } 39 | 40 | + (NSString *)FMDBTableName { 41 | return @"users"; 42 | } 43 | 44 | #pragma mark - MTLFMDBAdapter 45 | 46 | + (NSDictionary *)FMDBColumnsByPropertyKey { 47 | return @{ 48 | @"userId" : @"id", 49 | @"username" : @"name", 50 | @"avatar" : @"avatar", 51 | @"topicCount" : @"topic_count", 52 | @"replyCount" : @"reply_count", 53 | @"notificationCount" : [NSNull null], 54 | @"twitterAccount" : @"twitter_account", 55 | @"company" : @"company", 56 | @"city" : @"city", 57 | @"email" : @"email", 58 | @"introduction" : @"introduction", 59 | @"githubName" : @"github_name", 60 | @"githubURL" : @"github_url", 61 | @"realName" : @"real_name", 62 | @"blogURL" : @"personal_website", 63 | @"repliesUrl" : @"replies_web_view", 64 | @"createdAtDate" : @"created_at", 65 | @"updatedAtDate" : @"updated_at", 66 | }; 67 | } 68 | @end 69 | -------------------------------------------------------------------------------- /PHPHub/Utils/Helper/BaseHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseHelper.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseHelper : NSObject 12 | 13 | + (NSURL *)qiniuImageCenter:(NSString *)link 14 | withWidth:(NSString *)width 15 | withHeight:(NSString *)height; 16 | 17 | + (NSURL *)qiniuImageCenter:(NSString *)link 18 | withWidth:(NSString *)width 19 | withHeight:(NSString *)height 20 | mode:(NSInteger)model; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /PHPHub/Utils/Helper/BaseHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseHelper.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/22/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseHelper.h" 10 | 11 | @implementation BaseHelper 12 | 13 | // Center Square Image 14 | + (NSURL *)qiniuImageCenter:(NSString *)link 15 | withWidth:(NSString *)width 16 | withHeight:(NSString *)height { 17 | NSString *url = [[NSString alloc] init]; 18 | if([height isEqualToString:@"0"]) { 19 | url = [NSString stringWithFormat:@"%@?imageView2/2/w/%@/", link, width]; 20 | } else { 21 | url = [NSString stringWithFormat:@"%@?imageView/1/w/%@/h/%@", link, width, height]; 22 | } 23 | return [NSURL URLWithString:url]; 24 | } 25 | 26 | + (NSURL *)qiniuImageCenter:(NSString *)link 27 | withWidth:(NSString *)width 28 | withHeight:(NSString *)height 29 | mode:(NSInteger)model { 30 | NSString *url = [[NSString alloc] init]; 31 | url = [NSString stringWithFormat:@"%@?imageView/%ld/w/%@/h/%@", link, (long)model, width, height]; 32 | return [NSURL URLWithString:url]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/BaseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/BaseView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseView.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BaseView.h" 10 | 11 | @implementation BaseView 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame { 14 | self = [super initWithFrame:frame]; 15 | if (self) { 16 | self.backgroundColor = [UIColor clearColor]; 17 | self.layer.backgroundColor = [UIColor whiteColor].CGColor; 18 | self.layer.cornerRadius = 2; 19 | self.layer.borderColor = [UIColor colorWithRed:0.871 green:0.875 blue:0.878 alpha:1.000].CGColor; 20 | self.layer.borderWidth = 0.5; 21 | } 22 | return self; 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/BaseWebView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseWebView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/27/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseWebView : UIWebView 12 | @property (nonatomic, copy) NSString *urlString; 13 | - (instancetype)initWithFrame:(CGRect)frame urlString:(NSString *)urlString; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/BubbleButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // BubbleButton.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BubbleButton : UIButton 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/BubbleButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // BubbleButton.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/9/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "BubbleButton.h" 10 | #import 11 | 12 | @implementation BubbleButton 13 | 14 | - (instancetype)initWithFrame:(CGRect)frame { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | [self setup]; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 23 | self = [super initWithCoder:aDecoder]; 24 | if (self) { 25 | [self setup]; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)setup { 31 | [self addTarget:self action:@selector(scaleToSmall) forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter]; 32 | [self addTarget:self action:@selector(scaleAnimation) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; 33 | } 34 | 35 | - (void)scaleToSmall { 36 | POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; 37 | scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)]; 38 | scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0.7f, 0.7f)]; 39 | [self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleSmallAnimation"]; 40 | } 41 | 42 | - (void)scaleAnimation { 43 | POPSpringAnimation *scaleAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; 44 | scaleAnimation.velocity = [NSValue valueWithCGSize:CGSizeMake(3.f, 3.f)]; 45 | scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)]; 46 | scaleAnimation.springBounciness = 18.0f; 47 | 48 | __weak typeof(self) weakself = self; 49 | scaleAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) { 50 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 51 | [weakself scaleToDefault]; 52 | }); 53 | }; 54 | 55 | [self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleSpringAnimation"]; 56 | } 57 | 58 | - (void)scaleToDefault { 59 | POPBasicAnimation *scaleAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerScaleXY]; 60 | scaleAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(1.f, 1.f)]; 61 | [self.layer pop_addAnimation:scaleAnimation forKey:@"layerScaleDefaultAnimation"]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/SkipButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // SkipButton.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SkipButton : UIButton 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Base/SkipButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // SkipButton.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "SkipButton.h" 10 | 11 | @implementation SkipButton 12 | 13 | - (instancetype)init { 14 | self = [super init]; 15 | 16 | if (self) { 17 | [self setupSkipButton]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)setupSkipButton { 23 | self.width = 56; 24 | self.height = 30; 25 | 26 | self.backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.150]; 27 | [self setTitle:@"Skip" forState:UIControlStateNormal]; 28 | self.titleLabel.font = [UIFont fontWithName:FontName size:14]; 29 | 30 | self.layer.masksToBounds = YES; 31 | self.layer.cornerRadius = 7.5; 32 | self.layer.borderColor = [UIColor colorWithWhite:1.000 alpha:0.150].CGColor; 33 | self.layer.borderWidth = 1.5f; 34 | 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /PHPHub/Views/Comment/CommentListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommentListViewController.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/26/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CommentListViewController : UIViewController 12 | @property (nonatomic, strong) TopicEntity *topic; 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Comment/CommentListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CommentListViewController.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/26/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "CommentListViewController.h" 10 | #import "ReplyTopicViewController.h" 11 | #import "TOWebViewController.h" 12 | #import "BaseWebView.h" 13 | 14 | #import "AccessTokenHandler.h" 15 | 16 | @interface CommentListViewController () 17 | @property (nonatomic, strong) BaseWebView *commentsWebView; 18 | @end 19 | 20 | @implementation CommentListViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | self.navigationItem.title = @"评论列表"; 25 | 26 | [self.view addSubview:self.commentsWebView]; 27 | 28 | if (_topic.topicId > 0) { 29 | [self createRightBarButtonItem]; 30 | } 31 | } 32 | 33 | - (UIWebView *)commentsWebView { 34 | if (!_commentsWebView) { 35 | _commentsWebView = [[BaseWebView alloc] initWithFrame:self.view.bounds urlString:_topic.topicRepliesUrl]; 36 | } 37 | return _commentsWebView; 38 | } 39 | 40 | - (void)createRightBarButtonItem { 41 | if ([[CurrentUser Instance] isLogin]) { 42 | UIBarButtonItem *rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"edit_profile_icon"] 43 | style:UIBarButtonItemStylePlain 44 | target:self 45 | action:@selector(jumpToReplyTopicVC)]; 46 | rightBarButtonItem.tintColor = [UIColor colorWithRed:0.502 green:0.776 blue:0.200 alpha:1.000]; 47 | self.navigationItem.rightBarButtonItem = rightBarButtonItem; 48 | } 49 | } 50 | 51 | - (void)jumpToReplyTopicVC { 52 | ReplyTopicViewController *replyTopicVC = [[UIStoryboard storyboardWithName:@"Topic" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"replyTopic"]; 53 | replyTopicVC.topicId = _topic.topicId; 54 | replyTopicVC.delegate = self; 55 | [self.navigationController pushViewController:replyTopicVC animated:YES]; 56 | } 57 | 58 | #pragma mark Load WebView 59 | 60 | - (void)reloadCommentListView { 61 | [_commentsWebView reload]; 62 | } 63 | @end 64 | -------------------------------------------------------------------------------- /PHPHub/Views/LaunchAd/LaunchScreenAdView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchScreenAdView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/19/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SkipButton.h" 11 | 12 | @interface LaunchScreenAdView : UIView 13 | @property (nonatomic, assign) NSTimeInterval timePerImage; 14 | @property (nonatomic, strong) UIImageView *imageView; 15 | @property (nonatomic, assign) NSTimeInterval transitionDuration; 16 | @property (nonatomic, strong) UILabel *durationTimeLabel; 17 | @property (nonatomic) NSTimer *updateDurationLabelTimer; 18 | - (void)startAnimateWithImageLink:(NSURL *)url; 19 | @end -------------------------------------------------------------------------------- /PHPHub/Views/Notification/NotificationListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationListCell.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NotificationEntity.h" 11 | 12 | @interface NotificationListCell : UITableViewCell 13 | @property (nonatomic, strong) NotificationEntity *notificationEntity; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Views/Notification/NotificationListTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationListTableView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/26/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NotificationListTableView : UITableView 12 | @property (nonatomic, strong) NSMutableArray *notificationEntities; 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/EmptyTopicView.h: -------------------------------------------------------------------------------- 1 | // 2 | // EmptyTopicView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/23/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EmptyTopicView : UIView 12 | @end 13 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/EmptyTopicView.m: -------------------------------------------------------------------------------- 1 | // 2 | // EmptyTopicView.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/23/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "EmptyTopicView.h" 10 | #import "Masonry.h" 11 | 12 | @interface EmptyTopicView () 13 | @property (nonatomic) UIView *containerView; 14 | @property (nonatomic) UIImageView *emptyDataImage; 15 | @property (nonatomic) UILabel *hintLabel; 16 | @end 17 | 18 | @implementation EmptyTopicView 19 | - (instancetype)initWithFrame:(CGRect)frame { 20 | self = [super initWithFrame:frame]; 21 | 22 | if (self) { 23 | [self setUp]; 24 | [self addAutoLayout]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)setUp { 31 | [self addSubview:self.containerView]; 32 | } 33 | 34 | - (UIView *)containerView { 35 | if (_containerView == nil) { 36 | _containerView = [[UIView alloc] init]; 37 | [_containerView addSubview:self.emptyDataImage]; 38 | [_containerView addSubview:self.hintLabel]; 39 | } 40 | return _containerView; 41 | } 42 | 43 | - (UIImageView *)emptyDataImage { 44 | if (_emptyDataImage == nil) { 45 | _emptyDataImage = [[UIImageView alloc] init]; 46 | _emptyDataImage.image = [UIImage imageNamed:@"sad_face"]; 47 | } 48 | return _emptyDataImage; 49 | } 50 | 51 | - (UILabel *)hintLabel { 52 | if (_hintLabel == nil) { 53 | _hintLabel = [[UILabel alloc] init]; 54 | _hintLabel.font = [UIFont fontWithName:FontName size:18]; 55 | _hintLabel.textColor = [UIColor colorWithWhite:0.620 alpha:1.000]; 56 | _hintLabel.textAlignment = NSTextAlignmentCenter; 57 | _hintLabel.text = @"暂无数据"; 58 | } 59 | return _hintLabel; 60 | } 61 | 62 | - (void)addAutoLayout { 63 | [self.containerView mas_makeConstraints:^(MASConstraintMaker *make) { 64 | make.centerX.equalTo(self); 65 | make.centerY.equalTo(self); 66 | make.size.mas_equalTo(CGSizeMake(SCREEN_WIDTH, 230)); 67 | }]; 68 | 69 | [self.emptyDataImage mas_makeConstraints:^(MASConstraintMaker *make) { 70 | make.top.offset(0); 71 | make.centerX.equalTo(self); 72 | make.size.mas_equalTo(CGSizeMake(140, 140)); 73 | }]; 74 | 75 | [self.hintLabel mas_makeConstraints:^(MASConstraintMaker *make) { 76 | make.top.equalTo(self.emptyDataImage.mas_bottom).offset(30); 77 | make.centerX.equalTo(self); 78 | make.size.mas_equalTo(CGSizeMake(SCREEN_WIDTH, 20)); 79 | }]; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/TopicListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListCell.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TopicEntity.h" 11 | 12 | @interface TopicListCell : UITableViewCell 13 | @property (nonatomic, strong) TopicEntity *topicEntity; 14 | @end 15 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/TopicListTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListTableView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/23/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol TopicListTableViewDelegate 12 | - (void)headerRefreshing; 13 | - (void)footerRereshing; 14 | @end 15 | 16 | @interface TopicListTableView : UITableView 17 | @property (nonatomic, assign) BOOL shouldRemoveHeaderView; 18 | @property (nonatomic, strong) NSMutableArray *topicEntites; 19 | @property (nonatomic, weak) id topicListTableViewDelegate; 20 | - (void)setupFooterView; 21 | @end 22 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/TopicSearchBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicSearchBar.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/12/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TopicSearchBar : UISearchBar 12 | - (instancetype)initWithFrame:(CGRect)frame; 13 | @end 14 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/TopicSearchBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicSearchBar.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/12/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import "TopicSearchBar.h" 10 | 11 | @implementation TopicSearchBar 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame { 14 | self = [super initWithFrame:frame]; 15 | if (self) { 16 | self.placeholder = @"搜索"; 17 | self.backgroundColor = [UIColor groupTableViewBackgroundColor]; 18 | self.backgroundImage = [[UIImage alloc] init]; 19 | } 20 | return self; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PHPHub/Views/Topic/TopicVoteView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicVoteView.h 3 | // PHPHub 4 | // 5 | // Created by Aufree on 10/10/15. 6 | // Copyright © 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TopicVoteView : UIView 12 | @property (nonatomic, strong) UIButton *upVoteButton; 13 | @property (nonatomic, strong) UIButton *downVoteButton; 14 | - (instancetype)initWithFrame:(CGRect)frame topicEntity:(TopicEntity *)topic; 15 | @end 16 | -------------------------------------------------------------------------------- /PHPHub/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PHPHub 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. 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 | -------------------------------------------------------------------------------- /PHPHubTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | -------------------------------------------------------------------------------- /PHPHubTests/PHPHubTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PHPHubTests.m 3 | // PHPHubTests 4 | // 5 | // Created by Aufree on 9/21/15. 6 | // Copyright (c) 2015 ESTGroup. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface PHPHubTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation PHPHubTests 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 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | platform :ios, "8.0" 4 | 5 | target "PHPHub" do 6 | pod 'AFNetworking', '~> 2.0' 7 | pod 'AFOAuth2Manager' 8 | pod 'Qiniu' 9 | pod 'SDWebImage' 10 | pod 'Reachability' 11 | pod 'MBProgressHUD' 12 | pod 'DateTools' 13 | pod 'UIActivityIndicator-for-SDWebImage' 14 | pod 'CTAssetsPickerController' 15 | pod 'QBPopupMenu' 16 | pod 'Mantle', '1.5.5' 17 | pod 'FMDB', '~> 2.3' 18 | pod 'MTLFMDBAdapter', :git => 'https://github.com/summerblue/MTLFMDBAdapter' 19 | pod 'FMDBMigrationManager', '1.4' 20 | pod 'GVUserDefaults' 21 | pod 'Masonry' 22 | pod 'SVProgressHUD', '2.0.3' 23 | pod 'MJRefresh' 24 | pod 'UMengFeedback', '~> 2.3.4' 25 | pod 'UMengSocial', '4.2.3' 26 | pod 'QRCodeReaderViewController', :git => 'https://github.com/zhengjinghua/MQRCodeReaderViewController.git' 27 | pod 'UITextView+Placeholder' 28 | pod 'pop', '~> 1.0' 29 | pod 'FDFullscreenPopGesture', '1.1' 30 | pod 'UITableView+FDTemplateLayoutCell' 31 | pod 'UIActionSheet+Blocks' 32 | pod 'Fabric' 33 | pod 'Crashlytics' 34 | pod 'DZNEmptyDataSet' 35 | pod 'WebViewJavascriptBridge' 36 | pod 'JTSImageViewController' 37 | pod 'SAMKeychain' 38 | end 39 | --------------------------------------------------------------------------------