├── .gitignore ├── LICENSE ├── Podfile ├── README.md ├── ShareExtension ├── Base.lproj │ └── MainInterface.storyboard ├── Info.plist ├── ShareExtension.entitlements ├── ShareViewController.h └── ShareViewController.m ├── fansky.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── fansky.xcworkspace └── contents.xcworkspacedata ├── fansky ├── ARSegmentPager │ ├── ARSegmentPageController │ │ ├── ARSegmentControllerDelegate.h │ │ ├── ARSegmentPageController.h │ │ ├── ARSegmentPageController.m │ │ ├── ARSegmentPageControllerHeaderProtocol.h │ │ ├── ARSegmentPageHeader.h │ │ ├── ARSegmentPageHeader.m │ │ ├── ARSegmentView.h │ │ └── ARSegmentView.m │ ├── LICENSE │ └── README.md ├── Controllers │ ├── SAAboutViewController.h │ ├── SAAboutViewController.m │ ├── SAComposeViewController.h │ ├── SAComposeViewController.m │ ├── SAConversationViewController.h │ ├── SAConversationViewController.m │ ├── SAFavoriteTimeLineViewController.h │ ├── SAFavoriteTimeLineViewController.m │ ├── SAFriendListViewController.h │ ├── SAFriendListViewController.m │ ├── SALoginViewController.h │ ├── SALoginViewController.m │ ├── SAMentionListViewController.h │ ├── SAMentionListViewController.m │ ├── SAMessageViewController.h │ ├── SAMessageViewController.m │ ├── SAModifyInfoViewController.h │ ├── SAModifyInfoViewController.m │ ├── SAPhotoPreviewViewController.h │ ├── SAPhotoPreviewViewController.m │ ├── SAPhotoTimeLineViewController.h │ ├── SAPhotoTimeLineViewController.m │ ├── SASearchViewController.h │ ├── SASearchViewController.m │ ├── SASettingViewController.h │ ├── SASettingViewController.m │ ├── SASplashViewController.h │ ├── SASplashViewController.m │ ├── SAStatusViewController.h │ ├── SAStatusViewController.m │ ├── SATabBarViewController.h │ ├── SATabBarViewController.m │ ├── SATabBarViewControllerDelegate.h │ ├── SATabBarViewControllerDelegate.m │ ├── SATimeLineViewController.h │ ├── SATimeLineViewController.m │ ├── SAUserInfoViewController.h │ ├── SAUserInfoViewController.m │ ├── SAUserListViewController.h │ ├── SAUserListViewController.m │ ├── SAUserViewController.h │ └── SAUserViewController.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── AppIcon.png │ │ ├── Contents.json │ │ ├── Icon120-1.png │ │ ├── Icon120.png │ │ ├── Icon180.png │ │ ├── Icon58.png │ │ ├── Icon80.png │ │ └── Icon87.png │ ├── BackgroundAccount.imageset │ │ ├── BackgroundAccount@2x.png │ │ ├── BackgroundAccount@3x.png │ │ └── Contents.json │ ├── BackgroundAvatar.imageset │ │ ├── BackgroundAvatar@2x.png │ │ ├── BackgroundAvatar@3x.png │ │ └── Contents.json │ ├── BackgroundGrayLine.imageset │ │ ├── BackgroundGrayLine.png │ │ └── Contents.json │ ├── BackgroundImage.imageset │ │ ├── BackgroundImage.png │ │ └── Contents.json │ ├── Brand Assets.launchimage │ │ └── Contents.json │ ├── Contents.json │ ├── IconAt.imageset │ │ ├── Contents.json │ │ ├── IconAt@2x.png │ │ └── IconAt@3x.png │ ├── IconBackBlack.imageset │ │ ├── Contents.json │ │ ├── IconBack@2x.png │ │ └── IconBack@3x.png │ ├── IconBackColor.imageset │ │ ├── Contents.json │ │ ├── IconBackColor@2x.png │ │ └── IconBackColor@3x.png │ ├── IconBell.imageset │ │ ├── Contents.json │ │ ├── IconBell@2x.png │ │ └── IconBell@3x.png │ ├── IconCamera.imageset │ │ ├── Contents.json │ │ ├── IconCamera@2x.png │ │ └── IconCamera@3x.png │ ├── IconCameraCheck.imageset │ │ ├── Contents.json │ │ ├── IconCameraSelect@2x.png │ │ └── IconCameraSelect@3x.png │ ├── IconClose.imageset │ │ ├── Contents.json │ │ ├── IconClose@2x.png │ │ └── IconClose@3x.png │ ├── IconCompose.imageset │ │ ├── Contents.json │ │ ├── IconCompose@2x.png │ │ └── IconCompose@3x.png │ ├── IconFansky.imageset │ │ ├── Contents.json │ │ ├── IconFansky@2x.png │ │ └── IconFansky@3x.png │ ├── IconGIF.imageset │ │ ├── Contents.json │ │ ├── IconGIF.png │ │ └── IconGIF@3x.png │ ├── IconHome.imageset │ │ ├── Contents.json │ │ ├── IconHome@2x.png │ │ └── IconHome@3x.png │ ├── IconLock.imageset │ │ ├── Contents.json │ │ ├── IconLock@2x.png │ │ └── IconLock@3x.png │ ├── IconMail.imageset │ │ ├── Contents.json │ │ ├── IconMessage@2x.png │ │ └── IconMessage@3x.png │ ├── IconPerson.imageset │ │ ├── Contents.json │ │ ├── IconPerson@2x.png │ │ └── IconPerson@3x.png │ ├── IconReply.imageset │ │ ├── Contents.json │ │ ├── IconReply@2x.png │ │ └── IconReply@3x.png │ ├── IconReplySmall.imageset │ │ ├── Contents.json │ │ ├── IconReplySmall@2x.png │ │ └── IconReplySmall@3x.png │ ├── IconRepost.imageset │ │ ├── Contents.json │ │ ├── IconRepost@2x.png │ │ └── IconRepost@3x.png │ ├── IconRepostSmall.imageset │ │ ├── Contents.json │ │ ├── IconRepostSmall@2x.png │ │ └── IconRepostSmall@3x.png │ ├── IconSearch.imageset │ │ ├── Contents.json │ │ ├── IconSearch@2x.png │ │ └── IconSearch@3x.png │ ├── IconSetting.imageset │ │ ├── Contents.json │ │ ├── IconSetting@2x.png │ │ └── IconSetting@3x.png │ ├── IconShareContent.imageset │ │ ├── Contents.json │ │ ├── IconShareContent@2x.png │ │ └── IconShareContent@3x.png │ ├── IconStar.imageset │ │ ├── Contents.json │ │ ├── IconStar@2x.png │ │ └── IconStar@3x.png │ ├── IconStarSelected.imageset │ │ ├── Contents.json │ │ ├── IconStarHover@2x.png │ │ └── IconStarHover@3x.png │ ├── IconStop.imageset │ │ ├── Contents.json │ │ ├── IconStop@2x.png │ │ └── IconStop@3x.png │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Info.plist ├── Models │ ├── SAConversation+CoreDataProperties.h │ ├── SAConversation+CoreDataProperties.m │ ├── SAConversation.h │ ├── SAConversation.m │ ├── SAFriend.h │ ├── SAFriend.m │ ├── SAMessage+CoreDataProperties.h │ ├── SAMessage+CoreDataProperties.m │ ├── SAMessage.h │ ├── SAMessage.m │ ├── SAPhoto+CoreDataProperties.h │ ├── SAPhoto+CoreDataProperties.m │ ├── SAPhoto.h │ ├── SAPhoto.m │ ├── SAStatus+CoreDataProperties.h │ ├── SAStatus+CoreDataProperties.m │ ├── SAStatus.h │ ├── SAStatus.m │ ├── SATrend.h │ ├── SATrend.m │ ├── SAUser+CoreDataProperties.h │ ├── SAUser+CoreDataProperties.m │ ├── SAUser.h │ └── SAUser.m ├── SAAppDelegate.h ├── SAAppDelegate.m ├── SAConstants.h ├── SAConstants.m ├── Segues │ ├── SADismissAnimator.h │ ├── SADismissAnimator.m │ ├── SAPresentationAnimator.h │ ├── SAPresentationAnimator.m │ ├── SAPushWithoutAnimation.h │ └── SAPushWithoutAnimation.m ├── Services │ ├── SAAPIService.h │ ├── SAAPIService.m │ ├── SACacheManager.h │ ├── SACacheManager.m │ ├── SADataManager+Conversation.h │ ├── SADataManager+Conversation.m │ ├── SADataManager+Message.h │ ├── SADataManager+Message.m │ ├── SADataManager+Photo.h │ ├── SADataManager+Photo.m │ ├── SADataManager+Status.h │ ├── SADataManager+Status.m │ ├── SADataManager+User.h │ ├── SADataManager+User.m │ ├── SADataManager.h │ ├── SADataManager.m │ ├── SANotificationManager.h │ └── SANotificationManager.m ├── Utils │ ├── NSDate+Utils.h │ ├── NSDate+Utils.m │ ├── NSString+Utils.h │ ├── NSString+Utils.m │ ├── SAFileUtils.h │ ├── SAFileUtils.m │ ├── SAMessageDisplayUtils.h │ ├── SAMessageDisplayUtils.m │ ├── UIColor+Utils.h │ ├── UIColor+Utils.m │ ├── UIImage+Utils.h │ └── UIImage+Utils.m ├── Views │ ├── SAConversationCell.h │ ├── SAConversationCell.m │ ├── SAFriendCell.h │ ├── SAFriendCell.m │ ├── SAMessageCell.h │ ├── SAMessageCell.m │ ├── SAPhotoTimeLineCell.h │ ├── SAPhotoTimeLineCell.m │ ├── SATimeLineCell.h │ ├── SATimeLineCell.m │ ├── SATimeLineCell.xib │ ├── SATrendCell.h │ ├── SATrendCell.m │ ├── SATrendCell.xib │ ├── SAUserCell.h │ ├── SAUserCell.m │ ├── SAUserHeaderView.h │ ├── SAUserHeaderView.m │ └── SAUserHeaderView.xib ├── fansky.entitlements ├── fansky.xcdatamodeld │ ├── .xccurrentversion │ ├── fansky 2.xcdatamodel │ │ └── contents │ ├── fansky 3.xcdatamodel │ │ └── contents │ ├── fansky 4.xcdatamodel │ │ └── contents │ ├── fansky 5.xcdatamodel │ │ └── contents │ ├── fansky 6.xcdatamodel │ │ └── contents │ ├── fansky 7.xcdatamodel │ │ └── contents │ └── fansky.xcdatamodel │ │ └── contents ├── main.m └── zh-Hans.lproj │ ├── LaunchScreen.xib │ ├── SAMain.storyboard │ ├── SAMine.storyboard │ └── SAOthers.storyboard └── fanskyTests ├── Info.plist └── fanskyTests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | .DS_Store 28 | Pods 29 | Podfile.lock 30 | xcshareddata 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Chihya Tsang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '10.0' 2 | use_frameworks! 3 | 4 | target 'fansky' do 5 | 6 | pod 'TDOAuth' 7 | pod 'SDWebImage', '~>3.7' 8 | #pod 'ARSegmentPager', :git => 'https://github.com/AugustRush/ARSegmentPager.git' 9 | pod 'JTSImageViewController' 10 | #TODO JSQMessagesViewController->MessageKit 11 | pod 'JSQMessagesViewController' 12 | pod 'WSProgressHUD' 13 | pod 'MWPhotoBrowser' 14 | pod 'VTAcknowledgementsViewController' 15 | pod 'DTCoreText' 16 | pod 'LTHPasscodeViewController' 17 | pod 'LGRefreshView' 18 | pod 'Fabric' 19 | pod 'Crashlytics' 20 | pod 'STPopup' 21 | 22 | end 23 | 24 | target 'ShareExtension' do 25 | 26 | pod 'TDOAuth' 27 | 28 | end 29 | 30 | target 'fanskyTests' do 31 | 32 | end 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 饭斯基 2 | 一款简洁的第三方饭否客户端 3 | 4 | 5 | 6 | ## 截屏 7 | 时间线 8 | 9 | ## 依赖 10 | - [Cocoapods](https://github.com/CocoaPods/CocoaPods) 0.39.0 + 11 | - iOS 9.0+ 12 | - Xcode 7.3+ 13 | 14 | ## 构建 15 | 饭斯基使用[Cocoapods](https://github.com/CocoaPods/CocoaPods)构建 16 | 17 | ## URL Schemes 18 | - fansky://compose 快速发饭 19 | - fansky://search 搜索 20 | 21 | ## 许可证 22 | 23 | This code is distributed under the terms and conditions of the MIT license. 24 | 25 | ``` 26 | Copyright (C) 2016 Zhiya Zang 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy of 29 | this software and associated documentation files (the "Software"), to deal in 30 | the Software without restriction, including without limitation the rights to 31 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 32 | the Software, and to permit persons to whom the Software is furnished to do so, 33 | subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in all 36 | copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 40 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 41 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 42 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 43 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 44 | ``` 45 | 46 | 47 | -------------------------------------------------------------------------------- /ShareExtension/Base.lproj/MainInterface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ShareExtension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleDisplayName 8 | 饭斯基 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIcons 12 | 13 | CFBundleIcons~ipad 14 | 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | 饭斯基 21 | CFBundlePackageType 22 | XPC! 23 | CFBundleShortVersionString 24 | 1.6 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 125 29 | NSAppTransportSecurity 30 | 31 | NSAllowsArbitraryLoads 32 | 33 | 34 | NSExtension 35 | 36 | NSExtensionAttributes 37 | 38 | NSExtensionActivationRule 39 | 40 | NSExtensionActivationSupportsImageWithMaxCount 41 | 1 42 | NSExtensionActivationSupportsText 43 | 44 | NSExtensionActivationSupportsWebURLWithMaxCount 45 | 1 46 | 47 | 48 | NSExtensionMainStoryboard 49 | MainInterface 50 | NSExtensionPointIdentifier 51 | com.apple.share-services 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /ShareExtension/ShareExtension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.fansky 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ShareExtension/ShareViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.h 3 | // ShareExtension 4 | // 5 | // Created by Zzy on 16/5/30. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ShareViewController : SLComposeServiceViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ShareExtension/ShareViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShareViewController.m 3 | // ShareExtension 4 | // 5 | // Created by Zzy on 16/5/30. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import "ShareViewController.h" 10 | #import "SAAPIService.h" 11 | #import "SADataManager+User.h" 12 | 13 | @interface ShareViewController () 14 | 15 | @end 16 | 17 | @implementation ShareViewController 18 | 19 | - (BOOL)isContentValid 20 | { 21 | if (self.contentText.length > 140) { 22 | return NO; 23 | } 24 | return YES; 25 | } 26 | 27 | - (void)didSelectPost 28 | { 29 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 30 | if (!currentUser) { 31 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; 32 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"请在饭斯基App中登录一个饭否账号" message:nil preferredStyle:UIAlertControllerStyleAlert]; 33 | [alertController addAction:okAction]; 34 | [self presentViewController:alertController animated:YES completion:nil]; 35 | return; 36 | } 37 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 38 | __block NSData *imageData; 39 | __block NSString *extraString; 40 | NSExtensionItem *item = self.extensionContext.inputItems.firstObject; 41 | for (NSItemProvider *provider in item.attachments) { 42 | NSString *dataType = provider.registeredTypeIdentifiers.firstObject; 43 | if ([dataType isEqualToString:@"public.image"]) { 44 | [provider loadItemForTypeIdentifier:dataType options:nil completionHandler:^(UIImage *image, NSError *error){ 45 | imageData = UIImageJPEGRepresentation(image, 0.5); 46 | }]; 47 | } else if ([dataType isEqualToString:@"public.plain-text"]){ 48 | [provider loadItemForTypeIdentifier:dataType options:nil completionHandler:^(NSString *contentText, NSError *error){ 49 | extraString = contentText; 50 | }]; 51 | } else if ([dataType isEqualToString:@"public.url"]){ 52 | [provider loadItemForTypeIdentifier:dataType options:nil completionHandler:^(NSURL *url, NSError *error){ 53 | extraString = url.absoluteString; 54 | }]; 55 | } 56 | } 57 | 58 | NSString *status = self.contentText; 59 | if (extraString) { 60 | status = [NSString stringWithFormat:@"%@ %@", self.contentText, extraString]; 61 | } 62 | [[SAAPIService sharedSingleton] sendStatus:status replyToStatusID:nil repostStatusID:nil image:imageData success:nil failure:nil]; 63 | }); 64 | 65 | [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil]; 66 | } 67 | 68 | - (NSArray *)configurationItems { 69 | return @[]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /fansky.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fansky.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentControllerDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentControllerDelegate.h 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/29. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol ARSegmentControllerDelegate 12 | 13 | -(NSString *)segmentTitle; 14 | 15 | @optional 16 | -(UIScrollView *)streachScrollView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentPageController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentPageController.h 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/28. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARSegmentControllerDelegate.h" 11 | #import "ARSegmentPageHeader.h" 12 | #import "ARSegmentPageControllerHeaderProtocol.h" 13 | 14 | @interface ARSegmentPageController : UIViewController 15 | 16 | @property (nonatomic, assign) CGFloat segmentHeight; 17 | @property (nonatomic, assign) CGFloat headerHeight; 18 | @property (nonatomic, assign) CGFloat segmentMiniTopInset; 19 | @property (nonatomic, assign, readonly) CGFloat segmentToInset; 20 | 21 | @property (nonatomic, weak, readonly) UIViewController *currentDisplayController; 22 | 23 | @property (nonatomic, strong, readonly) UIView *headerView; 24 | 25 | @property (nonatomic, assign) BOOL freezenHeaderWhenReachMaxHeaderHeight; 26 | 27 | -(instancetype)initWithControllers:(UIViewController *)controller,... NS_REQUIRES_NIL_TERMINATION; 28 | 29 | -(void)setViewControllers:(NSArray *)viewControllers; 30 | 31 | //override this method to custom your own header view 32 | -(UIView *)customHeaderView; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentPageControllerHeaderProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentPageControllerHeaderProtocol.h 3 | // Board 4 | // 5 | // Created by August on 15/5/5. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @protocol ARSegmentPageControllerHeaderProtocol 12 | 13 | @property (nonatomic) UIImageView *imageView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentPageHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentPageHeader.h 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/28. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARSegmentPageControllerHeaderProtocol.h" 11 | 12 | @interface ARSegmentPageHeader : UIView 13 | 14 | @property (nonatomic, strong) UIImageView *imageView; 15 | 16 | @end -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentPageHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentPageHeader.m 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/28. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import "ARSegmentPageHeader.h" 10 | 11 | @interface ARSegmentPageHeader () 12 | 13 | @property (nonatomic, strong) NSLayoutConstraint *imageTopConstraint; 14 | 15 | @end 16 | 17 | @implementation ARSegmentPageHeader 18 | 19 | -(instancetype)init 20 | { 21 | self = [super init]; 22 | if (self) { 23 | [self _baseConfigs]; 24 | } 25 | return self; 26 | } 27 | 28 | -(void)_baseConfigs 29 | { 30 | self.imageView = [[UIImageView alloc] init]; 31 | self.imageView.image = [UIImage imageNamed:@"listdownload.jpg"]; 32 | self.imageView.contentMode = UIViewContentModeScaleAspectFill; 33 | self.imageView.clipsToBounds = YES; 34 | [self addSubview:self.imageView]; 35 | 36 | self.imageView.translatesAutoresizingMaskIntoConstraints = NO; 37 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0]]; 38 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0]]; 39 | self.imageTopConstraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0]; 40 | [self addConstraint:self.imageTopConstraint]; 41 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0]]; 42 | 43 | } 44 | 45 | -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 46 | { 47 | UIView *view = [super hitTest:point withEvent:event]; 48 | if (view == self) { 49 | return nil; 50 | } 51 | return view; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentView.h 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/28. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ARSegmentView : UIView 12 | 13 | @property (nonatomic, strong,readonly) UISegmentedControl *segmentControl; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/ARSegmentPageController/ARSegmentView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ARSegmentView.m 3 | // ARSegmentPager 4 | // 5 | // Created by August on 15/3/28. 6 | // Copyright (c) 2015年 August. All rights reserved. 7 | // 8 | 9 | #import "ARSegmentView.h" 10 | 11 | @implementation ARSegmentView 12 | { 13 | UIView *_bottomLine; 14 | } 15 | 16 | #pragma mark - init methods 17 | 18 | -(instancetype)init 19 | { 20 | self = [super init]; 21 | if (self) { 22 | [self _baseConfigs]; 23 | } 24 | return self; 25 | } 26 | 27 | #pragma mark - private methods 28 | 29 | -(void)_baseConfigs 30 | { 31 | // self.translucent = NO; 32 | self.backgroundColor = [UIColor colorWithRed:244/255.0 green:244/255.0 blue:244/255.0 alpha:1.0]; 33 | _segmentControl = [[UISegmentedControl alloc] init]; 34 | _segmentControl.selectedSegmentIndex = 0; 35 | [self addSubview:self.segmentControl]; 36 | 37 | _bottomLine = [[UIView alloc] init]; 38 | _bottomLine.backgroundColor = [UIColor lightGrayColor]; 39 | [self addSubview:_bottomLine]; 40 | 41 | self.segmentControl.translatesAutoresizingMaskIntoConstraints = NO; 42 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.segmentControl attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; 43 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.segmentControl attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; 44 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.segmentControl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1 constant:-14]]; 45 | [self addConstraint:[NSLayoutConstraint constraintWithItem:self.segmentControl attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1 constant:-16]]; 46 | 47 | _bottomLine.translatesAutoresizingMaskIntoConstraints = NO; 48 | [self addConstraint:[NSLayoutConstraint constraintWithItem:_bottomLine attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1 constant:0]]; 49 | [self addConstraint:[NSLayoutConstraint constraintWithItem:_bottomLine attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]]; 50 | [_bottomLine addConstraint:[NSLayoutConstraint constraintWithItem:_bottomLine attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:1]]; 51 | [self addConstraint:[NSLayoutConstraint constraintWithItem:_bottomLine attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0]]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /fansky/ARSegmentPager/README.md: -------------------------------------------------------------------------------- 1 | ## ARSegmentPager 2 | ##### ARSegmentPager is a fully custom UITabbarController-likely controller with parallax header. 3 | 4 | ### ARSegmentPager(snapshots in my app) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ### Usage 17 | 18 | * Manualy: 19 | 20 | just drag the 'ARSegmentPageController' document to your project. 21 | 22 | * Cocoapods: 23 | 24 | pod 'ARSegmentPager', :git => 'https://github.com/AugustRush/ARSegmentPager.git' 25 | 26 | ### TODO: 27 | 28 | * Swift Version 29 | 30 | ### Supplement 31 | 32 | * if you have any question or idea about this control, send email to me 'liupingwei30@gmail.com'. -------------------------------------------------------------------------------- /fansky/Controllers/SAAboutViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAAboutViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/5/18. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAAboutViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SAAboutViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAAboutViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/5/18. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAAboutViewController.h" 10 | #import "UIColor+Utils.h" 11 | #import 12 | 13 | @interface SAAboutViewController () 14 | 15 | @property (weak, nonatomic) IBOutlet UIImageView *logoImageView; 16 | @property (weak, nonatomic) IBOutlet UILabel *versionLabel; 17 | @property (weak, nonatomic) IBOutlet UITextView *introTextView; 18 | 19 | @end 20 | 21 | @implementation SAAboutViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | 27 | [self updateInterface]; 28 | } 29 | 30 | - (void)updateInterface 31 | { 32 | self.logoImageView.layer.borderColor = [UIColor lightGrayColor].CGColor; 33 | 34 | NSString *introString = self.introTextView.text; 35 | NSMutableAttributedString *introAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.introTextView.attributedText]; 36 | [introAttributedString addAttribute:NSLinkAttributeName value:@"fansky://acknowledgements" range:[introString rangeOfString:@"致谢"]]; 37 | [introAttributedString addAttribute:NSLinkAttributeName value:@"fansky://opensource" range:[introString rangeOfString:@"开源" options:NSBackwardsSearch]]; 38 | self.introTextView.attributedText = introAttributedString; 39 | 40 | NSDictionary *linkAttributes = @{NSForegroundColorAttributeName: [UIColor fanskyBlue], 41 | NSUnderlineColorAttributeName: [UIColor fanskyBlue], 42 | NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}; 43 | self.introTextView.linkTextAttributes = linkAttributes; 44 | 45 | NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; 46 | NSString *versionString = [NSString stringWithFormat:@"饭斯基 %@ (%@)", [info objectForKey:@"CFBundleShortVersionString"], [info objectForKey:@"CFBundleVersion"]]; 47 | self.versionLabel.text = versionString; 48 | } 49 | 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | } 54 | 55 | #pragma mark - UITextViewDelegate 56 | 57 | - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange 58 | { 59 | if ([URL.absoluteString isEqualToString:@"fansky://acknowledgements"]) { 60 | NSString *path = [[NSBundle mainBundle] pathForResource:@"Pods-fansky-acknowledgements" ofType:@"plist"]; 61 | VTAcknowledgementsViewController *acknowledgementViewController = [[VTAcknowledgementsViewController alloc] initWithAcknowledgementsPlistPath:path]; 62 | acknowledgementViewController.title = @"致谢"; 63 | acknowledgementViewController.headerText = @"饭斯基使用了如下开源组件"; 64 | acknowledgementViewController.footerText = @"使用 CocoaPods 生成"; 65 | [self.navigationController showViewController:acknowledgementViewController sender:nil]; 66 | } else if ([URL.absoluteString isEqualToString:@"fansky://opensource"]) { 67 | NSURL *fanskyURL = [NSURL URLWithString:@"https://github.com/simpleapples/fansky"]; 68 | [[UIApplication sharedApplication] openURL:fanskyURL]; 69 | } 70 | return YES; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /fansky/Controllers/SAComposeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAComposeViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAStatus; 12 | 13 | @interface SAComposeViewController : UIViewController 14 | 15 | @property (copy, nonatomic) NSString *userID; 16 | @property (strong, nonatomic) SAStatus *replyToStatus; 17 | @property (strong, nonatomic) SAStatus *repostStatus; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /fansky/Controllers/SAConversationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversationViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAConversationViewController : UITableViewController 12 | 13 | - (void)showFriendPopup; 14 | - (void)refreshData; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/Controllers/SAFavoriteTimeLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAFavoriteTimeLineViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/18/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SATimeLineViewController.h" 11 | 12 | @interface SAFavoriteTimeLineViewController : SATimeLineViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fansky/Controllers/SAFavoriteTimeLineViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAFavoriteTimeLineViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/18/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAFavoriteTimeLineViewController.h" 10 | #import "SAMessageDisplayUtils.h" 11 | #import "SADataManager+Status.h" 12 | #import "SAAPIService.h" 13 | #import "SAStatusViewController.h" 14 | #import "SAUserViewController.h" 15 | #import "SATimeLineCell.h" 16 | #import "SAStatus+CoreDataProperties.h" 17 | #import "SAUser+CoreDataProperties.h" 18 | 19 | @interface SAFavoriteTimeLineViewController () 20 | 21 | @property (nonatomic) NSUInteger page; 22 | 23 | @end 24 | 25 | @implementation SAFavoriteTimeLineViewController 26 | 27 | static NSString *const ENTITY_NAME = @"SAStatus"; 28 | static NSUInteger FAVORITE_TIME_LINE_COUNT = 40; 29 | 30 | - (void)getLocalData 31 | { 32 | [self refreshData]; 33 | } 34 | 35 | - (void)updateDataWithRefresh:(BOOL)refresh 36 | { 37 | if (!refresh) { 38 | self.page++; 39 | } else { 40 | self.page = 1; 41 | } 42 | void (^success)(id data) = ^(id data) { 43 | NSArray *originalList = (NSArray *)data; 44 | __block NSMutableArray *tempTimeLineList = [[NSMutableArray alloc] init]; 45 | [originalList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 46 | SAStatus *status = [[SADataManager sharedManager] statusWithObject:obj localUsers:nil type:SAStatusTypeFavoriteStatus]; 47 | [tempTimeLineList addObject:status]; 48 | }]; 49 | if (self.page > 1) { 50 | self.timeLineList = [self.timeLineList arrayByAddingObjectsFromArray:tempTimeLineList]; 51 | } else { 52 | self.timeLineList = [[NSArray alloc] initWithArray:tempTimeLineList]; 53 | } 54 | [self.tableView reloadData]; 55 | [SAMessageDisplayUtils dismiss]; 56 | dispatch_async(dispatch_get_main_queue(), ^{ 57 | [self.refreshView endRefreshing]; 58 | }); 59 | }; 60 | void (^failure)(NSString *error) = ^(NSString *error) { 61 | [SAMessageDisplayUtils showInfoWithMessage:error]; 62 | dispatch_async(dispatch_get_main_queue(), ^{ 63 | [self.refreshView endRefreshing]; 64 | }); 65 | }; 66 | 67 | if (refresh) { 68 | [SAMessageDisplayUtils showProgressWithMessage:@"正在刷新"]; 69 | } 70 | [[SAAPIService sharedSingleton] userFavoriteTimeLineWithUserID:self.userID count:FAVORITE_TIME_LINE_COUNT page:self.page success:success failure:failure]; 71 | } 72 | 73 | #pragma mark - SATimeLineCellDelegate 74 | 75 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell avatarImageViewTouchUp:(id)sender 76 | { 77 | self.selectedUserID = timeLineCell.status.user.userID; 78 | [self performSegueWithIdentifier:@"FavoriteTimeLineToUserSegue" sender:nil]; 79 | } 80 | 81 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell contentURLTouchUp:(id)sender 82 | { 83 | NSURL *url = timeLineCell.selectedURL; 84 | if ([url.host isEqualToString:@"fanfou.com"]) { 85 | self.selectedUserID = url.lastPathComponent; 86 | [self performSegueWithIdentifier:@"FavoriteTimeLineToUserSegue" sender:nil]; 87 | } else if ([url.scheme isEqualToString:@"http"] || [url.scheme isEqualToString:@"https"]) { 88 | [[UIApplication sharedApplication] openURL:url]; 89 | } 90 | } 91 | 92 | #pragma mark - UITableViewDelegate 93 | 94 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 95 | { 96 | SAStatus *status = [self.timeLineList objectAtIndex:indexPath.row]; 97 | self.selectedStatus = status; 98 | [self performSegueWithIdentifier:@"FavoriteTimeLineToStatusSegue" sender:nil]; 99 | } 100 | 101 | #pragma mark - ARSegmentControllerDelegate 102 | 103 | - (NSString *)segmentTitle 104 | { 105 | return @"收藏"; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /fansky/Controllers/SAFriendListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAFriendListViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/25/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_ENUM(NSUInteger, SAFriendListType) 13 | { 14 | SAFriendListTypeFollow, 15 | SAFriendListTypeFriend, 16 | SAFriendListTypeFriendPopup, 17 | SAFriendListTypeRequest 18 | }; 19 | 20 | @class SAFriendListViewController; 21 | @class SAFriend; 22 | 23 | @protocol SAFriendListViewControllerDelegate 24 | 25 | - (void)friendListViewController:(SAFriendListViewController *)friendListViewController selectedfriend:(SAFriend *)selectedFriend; 26 | 27 | @end 28 | 29 | @interface SAFriendListViewController : UITableViewController 30 | 31 | @property (weak, nonatomic) id delegate; 32 | @property (copy, nonatomic) NSString *userID; 33 | @property (assign, nonatomic) SAFriendListType type; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /fansky/Controllers/SALoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SALoginViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SALoginViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SALoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SALoginViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SALoginViewController.h" 10 | #import "SAAPIService.h" 11 | #import "SAConstants.h" 12 | #import "SADataManager+User.h" 13 | #import "SAUser+CoreDataProperties.h" 14 | #import "SAMessageDisplayUtils.h" 15 | 16 | @interface SALoginViewController () 17 | 18 | @property (weak, nonatomic) IBOutlet UITextField *emailTextField; 19 | @property (weak, nonatomic) IBOutlet UITextField *passwordTextField; 20 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *loginButton; 21 | 22 | @end 23 | 24 | @implementation SALoginViewController 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | } 30 | 31 | - (void)viewWillAppear:(BOOL)animated 32 | { 33 | [self.emailTextField becomeFirstResponder]; 34 | [super viewWillAppear:animated]; 35 | } 36 | 37 | - (void)viewWillDisappear:(BOOL)animated 38 | { 39 | [self.view endEditing:YES]; 40 | [super viewWillDisappear:animated]; 41 | } 42 | 43 | - (void)didReceiveMemoryWarning 44 | { 45 | [super didReceiveMemoryWarning]; 46 | } 47 | 48 | - (void)login 49 | { 50 | self.loginButton.enabled = NO; 51 | [SAMessageDisplayUtils showProgressWithMessage:@"正在登录"]; 52 | 53 | NSString *email = self.emailTextField.text; 54 | NSString *password = self.passwordTextField.text; 55 | 56 | [[SAAPIService sharedSingleton] authorizeWithUsername:email password:password success:^(NSString *token, NSString *secret) { 57 | [[SAAPIService sharedSingleton] verifyCredentialsWithToken:token secret:secret success:^(id data) { 58 | self.loginButton.enabled = YES; 59 | [SAMessageDisplayUtils showSuccessWithMessage:@"登录成功"]; 60 | [[SADataManager sharedManager] insertOrUpdateUserWithObject:data local:YES active:YES token:token secret:secret]; 61 | [self performSegueWithIdentifier:@"LoginExitToUserListSegue" sender:nil]; 62 | } failure:^(NSString *error) { 63 | self.loginButton.enabled = YES; 64 | [SAMessageDisplayUtils showErrorWithMessage:error]; 65 | }]; 66 | } failure:^(NSString *error) { 67 | self.loginButton.enabled = YES; 68 | [SAMessageDisplayUtils showErrorWithMessage:error]; 69 | }]; 70 | } 71 | 72 | #pragma mark - UITextFieldDelegate 73 | 74 | - (BOOL)textFieldShouldReturn:(UITextField *)textField 75 | { 76 | if (textField.tag == 1) { 77 | [self.passwordTextField becomeFirstResponder]; 78 | } else if (textField.tag == 2) { 79 | [self login]; 80 | } 81 | return YES; 82 | } 83 | 84 | #pragma mark - EventHandler 85 | 86 | - (IBAction)loginButtonTouchUp:(id)sender 87 | { 88 | [self login]; 89 | } 90 | 91 | - (IBAction)cancelButtonTouchUp:(id)sender 92 | { 93 | [self performSegueWithIdentifier:@"LoginExitToUserListSegue" sender:nil]; 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /fansky/Controllers/SAMentionListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMentionListViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/18/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SATimeLineViewController.h" 11 | 12 | @interface SAMentionListViewController : SATimeLineViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fansky/Controllers/SAMentionListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMentionListViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/18/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAMentionListViewController.h" 10 | #import "SADataManager+User.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import "SAStatusViewController.h" 13 | #import "SADataManager+Status.h" 14 | #import "SAMessageDisplayUtils.h" 15 | #import "SAStatus+CoreDataProperties.h" 16 | #import "SAAPIService.h" 17 | #import "SAUserViewController.h" 18 | #import "SATimeLineCell.h" 19 | 20 | @interface SAMentionListViewController () 21 | 22 | @property (copy, nonatomic) NSString *maxID; 23 | 24 | @end 25 | 26 | @implementation SAMentionListViewController 27 | 28 | static NSString *const ENTITY_NAME = @"SAStatus"; 29 | static NSUInteger TIME_LINE_COUNT = 40; 30 | 31 | - (void)getLocalData 32 | { 33 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 34 | [[SADataManager sharedManager] currentMentionTimeLineWithUserID:currentUser.userID offset:0 limit:TIME_LINE_COUNT completeHandler:^(NSArray *result) { 35 | self.timeLineList = result; 36 | [self.tableView reloadData]; 37 | [self refreshData]; 38 | }]; 39 | } 40 | 41 | - (void)updateDataWithRefresh:(BOOL)refresh 42 | { 43 | NSString *maxID; 44 | if (!refresh) { 45 | maxID = self.maxID; 46 | } else if (self.timeLineList.count) { 47 | [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 48 | } 49 | NSString *userID = [SADataManager sharedManager].currentUser.userID; 50 | void (^success)(id data) = ^(id data) { 51 | [[SADataManager sharedManager] insertOrUpdateStatusWithObjects:data type:SAStatusTypeMentionStatus]; 52 | NSUInteger offset = self.timeLineList.count; 53 | if (refresh) { 54 | offset = 0; 55 | } 56 | [[SADataManager sharedManager] currentMentionTimeLineWithUserID:userID offset:offset limit:TIME_LINE_COUNT completeHandler:^(NSArray *result) { 57 | if (refresh) { 58 | self.timeLineList = result; 59 | } else { 60 | self.timeLineList = [self.timeLineList arrayByAddingObjectsFromArray:result]; 61 | } 62 | if (self.timeLineList.count) { 63 | SAStatus *lastStatus = [self.timeLineList lastObject]; 64 | self.maxID = lastStatus.statusID; 65 | } 66 | [self.tableView reloadData]; 67 | dispatch_async(dispatch_get_main_queue(), ^{ 68 | [self.refreshView endRefreshing]; 69 | }); 70 | }]; 71 | }; 72 | void (^failure)(NSString *error) = ^(NSString *error) { 73 | [SAMessageDisplayUtils showErrorWithMessage:error]; 74 | dispatch_async(dispatch_get_main_queue(), ^{ 75 | [self.refreshView endRefreshing]; 76 | }); 77 | }; 78 | 79 | if (refresh) { 80 | dispatch_async(dispatch_get_main_queue(), ^{ 81 | [self.refreshView triggerAnimated:YES]; 82 | }); 83 | } 84 | [[SAAPIService sharedSingleton] mentionStatusWithSinceID:nil maxID:maxID count:TIME_LINE_COUNT success:success failure:failure]; 85 | } 86 | 87 | #pragma mark - SATimeLineCellDelegate 88 | 89 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell avatarImageViewTouchUp:(id)sender 90 | { 91 | self.selectedUserID = timeLineCell.status.user.userID; 92 | [self performSegueWithIdentifier:@"MentionListToUserSegue" sender:nil]; 93 | } 94 | 95 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell contentURLTouchUp:(id)sender 96 | { 97 | NSURL *url = timeLineCell.selectedURL; 98 | if ([url.host isEqualToString:@"fanfou.com"]) { 99 | self.selectedUserID = url.lastPathComponent; 100 | [self performSegueWithIdentifier:@"MentionListToUserSegue" sender:nil]; 101 | } else if ([url.scheme isEqualToString:@"http"] || [url.scheme isEqualToString:@"https"]) { 102 | [[UIApplication sharedApplication] openURL:url]; 103 | } 104 | } 105 | 106 | #pragma mark - UITableViewDelegate 107 | 108 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 109 | { 110 | SAStatus *status = [self.timeLineList objectAtIndex:indexPath.row]; 111 | self.selectedStatus = status; 112 | [self performSegueWithIdentifier:@"MentionListToStatusSegue" sender:nil]; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /fansky/Controllers/SAMessageViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessageViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAMessageViewController : JSQMessagesViewController 12 | 13 | @property (copy, nonatomic) NSString *userID; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fansky/Controllers/SAModifyInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAModifyInfoViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/10. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAModifyInfoViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SAPhotoPreviewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhotoPreviewViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 12/27/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAStatus; 12 | 13 | @interface SAPhotoPreviewViewController : UIViewController 14 | 15 | @property (strong, nonatomic) SAStatus *status; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Controllers/SAPhotoPreviewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhotoPreviewViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 12/27/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAPhotoPreviewViewController.h" 10 | #import "SAStatus+CoreDataProperties.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import "SAPhoto+CoreDataProperties.h" 13 | #import "SADataManager+Status.h" 14 | #import "SAMessageDisplayUtils.h" 15 | #import "NSDate+Utils.h" 16 | #import 17 | 18 | @interface SAPhotoPreviewViewController () 19 | 20 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 21 | @property (weak, nonatomic) IBOutlet UILabel *usernameLabel; 22 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel; 23 | @property (weak, nonatomic) IBOutlet UIImageView *contentImageView; 24 | 25 | @end 26 | 27 | @implementation SAPhotoPreviewViewController 28 | 29 | - (void)viewDidLoad 30 | { 31 | [super viewDidLoad]; 32 | 33 | [self updateInterface]; 34 | } 35 | 36 | - (void)updateInterface 37 | { 38 | self.usernameLabel.text = self.status.user.name; 39 | self.timeLabel.text = [self.status.createdAt friendlyDateString]; 40 | [self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:self.status.user.profileImageURL] placeholderImage:[UIImage imageNamed:@"BackgroundAvatar"] options:SDWebImageRefreshCached]; 41 | self.contentImageView.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1].CGColor; 42 | 43 | if (self.status.photo.largeURL) { 44 | [self.contentImageView sd_setImageWithURL:[NSURL URLWithString:self.status.photo.largeURL] placeholderImage:nil options:SDWebImageRefreshCached]; 45 | } 46 | } 47 | 48 | - (NSArray> *)previewActionItems 49 | { 50 | UIPreviewAction *saveToAlbumAction = [UIPreviewAction actionWithTitle:@"保存到相册" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { 51 | if (self.contentImageView.image) { 52 | UIImageWriteToSavedPhotosAlbum(self.contentImageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); 53 | } 54 | }]; 55 | return @[saveToAlbumAction]; 56 | } 57 | 58 | - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 59 | { 60 | if (error) { 61 | [SAMessageDisplayUtils showErrorWithMessage:@"保存失败"]; 62 | } else { 63 | [SAMessageDisplayUtils showSuccessWithMessage:@"已保存到相册"]; 64 | } 65 | } 66 | 67 | - (void)didReceiveMemoryWarning 68 | { 69 | [super didReceiveMemoryWarning]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /fansky/Controllers/SAPhotoTimeLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhotoTimeLineViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARSegmentPageController.h" 11 | 12 | @interface SAPhotoTimeLineViewController : UICollectionViewController 13 | 14 | @property (copy, nonatomic) NSString *userID; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/Controllers/SASearchViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SASearchViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/27/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, SASearchViewControllerType) 12 | { 13 | SASearchViewControllerTypeTrend = 1, 14 | SASearchViewControllerTypeSearch = 2, 15 | SASearchViewControllerTypeRandom = 3 16 | }; 17 | 18 | @interface SASearchViewController : UIViewController 19 | 20 | @property (nonatomic) SASearchViewControllerType type; 21 | @property (copy, nonatomic) NSString *keyword; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /fansky/Controllers/SASettingViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SASettingViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SASettingViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SASettingViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SASettingViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SASettingViewController.h" 10 | #import "SAUserViewController.h" 11 | #import "SAFriendListViewController.h" 12 | #import "SADataManager+User.h" 13 | #import "SAUser+CoreDataProperties.h" 14 | #import "SANotificationManager.h" 15 | #import 16 | #import 17 | 18 | @interface SASettingViewController () 19 | 20 | @property (weak, nonatomic) IBOutlet UILabel *friendRequestCountLabel; 21 | @property (weak, nonatomic) IBOutlet UISwitch *passcodeSwitch; 22 | @property (weak, nonatomic) IBOutlet UILabel *cacheSizeLabel; 23 | 24 | @end 25 | 26 | @implementation SASettingViewController 27 | 28 | - (void)viewDidLoad 29 | { 30 | [super viewDidLoad]; 31 | 32 | [LTHPasscodeViewController sharedUser].delegate = self; 33 | 34 | [self updateInterface]; 35 | } 36 | 37 | - (void)viewWillAppear:(BOOL)animated 38 | { 39 | [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated]; 40 | [super viewWillAppear:animated]; 41 | } 42 | 43 | - (void)didReceiveMemoryWarning 44 | { 45 | [super didReceiveMemoryWarning]; 46 | } 47 | 48 | - (void)updatePasscodeSwitch 49 | { 50 | self.passcodeSwitch.on = [LTHPasscodeViewController doesPasscodeExist]; 51 | } 52 | 53 | - (void)updateInterface 54 | { 55 | self.friendRequestCountLabel.text = [NSString stringWithFormat:@"%ld", [SANotificationManager sharedManager].friendRequestCount]; 56 | 57 | [self updatePasscodeSwitch]; 58 | 59 | [self updateCacheSize]; 60 | } 61 | 62 | - (void)updateCacheSize 63 | { 64 | [[SDImageCache sharedImageCache] calculateSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize) { 65 | self.cacheSizeLabel.text = [NSByteCountFormatter stringFromByteCount:totalSize countStyle:NSByteCountFormatterCountStyleFile]; 66 | }]; 67 | } 68 | 69 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 70 | { 71 | if ([segue.destinationViewController isKindOfClass:[SAFriendListViewController class]]) { 72 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 73 | SAFriendListViewController *friendListViewController = (SAFriendListViewController *)segue.destinationViewController; 74 | friendListViewController.type = SAFriendListTypeRequest; 75 | friendListViewController.userID = currentUser.userID; 76 | } 77 | } 78 | 79 | #pragma mark - UITableViewDelegate 80 | 81 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 82 | { 83 | UINavigationController *navigationController = (UINavigationController *)self.navigationController.presentingViewController; 84 | if (indexPath.section == 0) { 85 | if (indexPath.row == 0) { 86 | [self performSegueWithIdentifier:@"SettingToFriendListSegue" sender:nil]; 87 | } 88 | } else if (indexPath.section == 1) { 89 | if (indexPath.row == 1) { 90 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 91 | [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{ 92 | [self updateCacheSize]; 93 | }]; 94 | } 95 | } else if (indexPath.section == 2) { 96 | if (indexPath.row == 0) { 97 | [self dismissViewControllerAnimated:YES completion:^{ 98 | SAUserViewController *userViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"SAUserViewController"]; 99 | userViewController.userID = @"fansky"; 100 | dispatch_async(dispatch_get_main_queue(), ^{ 101 | [navigationController showViewController:userViewController sender:nil]; 102 | }); 103 | }]; 104 | } else if (indexPath.row == 1) { 105 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 106 | NSString *appID = @"1039622797"; 107 | NSString *url = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@", appID]; 108 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; 109 | } 110 | } 111 | } 112 | 113 | #pragma mark - LTHPasscodeViewControllerDelegate 114 | 115 | - (void)passcodeViewControllerWillClose 116 | { 117 | [self updatePasscodeSwitch]; 118 | } 119 | 120 | #pragma mark - EventHandler 121 | 122 | - (IBAction)closeButtonTouchUp:(id)sender 123 | { 124 | [self dismissViewControllerAnimated:YES completion:nil]; 125 | } 126 | 127 | - (IBAction)passcodeSwitchValueChanged:(id)sender 128 | { 129 | if (![LTHPasscodeViewController doesPasscodeExist]) { 130 | [[LTHPasscodeViewController sharedUser] showForEnablingPasscodeInViewController:self asModal:YES]; 131 | } else { 132 | [[LTHPasscodeViewController sharedUser] showForDisablingPasscodeInViewController:self asModal:YES]; 133 | } 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /fansky/Controllers/SASplashViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SASplashViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SASplashViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SASplashViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SASplashViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SASplashViewController.h" 10 | #import "SAConstants.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import "SADataManager+User.h" 13 | 14 | @interface SASplashViewController () 15 | 16 | @end 17 | 18 | @implementation SASplashViewController 19 | 20 | - (void)viewDidLoad 21 | { 22 | [super viewDidLoad]; 23 | 24 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 25 | dispatch_async(dispatch_get_main_queue(), ^{ 26 | if (currentUser) { 27 | [self performSegueWithIdentifier:@"SplashToTabBarSegue" sender:nil]; 28 | } else { 29 | [self performSegueWithIdentifier:@"SplashToUserListSegue" sender:nil]; 30 | } 31 | }); 32 | } 33 | 34 | - (void)didReceiveMemoryWarning 35 | { 36 | [super didReceiveMemoryWarning]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /fansky/Controllers/SAStatusViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStatusViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/15/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAStatus; 12 | 13 | @interface SAStatusViewController : UIViewController 14 | 15 | @property (strong, nonatomic) SAStatus *status; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Controllers/SATabBarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SATabBarViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SATabBarViewController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SATabBarViewControllerDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SATabBarViewControllerDelegate.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/1/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SATabBarViewControllerDelegate : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fansky/Controllers/SATabBarViewControllerDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SATabBarViewControllerDelegate.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/1/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SATabBarViewControllerDelegate.h" 10 | #import "SATimeLineViewController.h" 11 | #import "SAMentionListViewController.h" 12 | #import "SAConversationViewController.h" 13 | 14 | @implementation SATabBarViewControllerDelegate 15 | 16 | - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController 17 | { 18 | if ([tabBarController.selectedViewController isEqual:viewController]) { 19 | if (tabBarController.selectedIndex == 0) { 20 | SATimeLineViewController *timeLineViewController = (SATimeLineViewController *)viewController; 21 | [timeLineViewController refreshData]; 22 | } else if (tabBarController.selectedIndex == 1) { 23 | SAMentionListViewController *mentionListViewController = (SAMentionListViewController *)viewController; 24 | [mentionListViewController refreshData]; 25 | } else if (tabBarController.selectedIndex == 2) { 26 | SAConversationViewController *conversationViewController = (SAConversationViewController *)viewController; 27 | [conversationViewController refreshData]; 28 | } 29 | return NO; 30 | } 31 | return YES; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /fansky/Controllers/SATimeLineViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TimeLineViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARSegmentPageHeader.h" 11 | #import "LGRefreshView.h" 12 | 13 | @class SAStatus; 14 | 15 | @interface SATimeLineViewController : UITableViewController 16 | 17 | @property (strong, nonatomic) LGRefreshView *refreshView; 18 | 19 | @property (strong, nonatomic) NSArray *timeLineList; 20 | @property (copy, nonatomic) NSString *userID; 21 | @property (strong, nonatomic) SAStatus *selectedStatus; 22 | @property (copy, nonatomic) NSString *selectedUserID; 23 | 24 | - (void)refreshData; 25 | - (void)getLocalData; 26 | - (void)updateDataWithRefresh:(BOOL)refresh; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /fansky/Controllers/SAUserInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserInfoViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/23/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAUserInfoViewController : UIViewController 12 | 13 | @property (copy, nonatomic) NSString *userID; 14 | @property (weak, nonatomic) IBOutlet UIVisualEffectView *blurView; 15 | @property (weak, nonatomic) IBOutlet UILabel *infoLabel; 16 | @property (weak, nonatomic) IBOutlet UIButton *closeButton; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/Controllers/SAUserInfoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserInfoViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/23/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAUserInfoViewController.h" 10 | #import "SAUser+CoreDataProperties.h" 11 | #import "SADataManager+User.h" 12 | 13 | @interface SAUserInfoViewController () 14 | 15 | @property (strong, nonatomic) SAUser *user; 16 | 17 | @end 18 | 19 | @implementation SAUserInfoViewController 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | 25 | self.user = [[SADataManager sharedManager] userWithID:self.userID]; 26 | if (self.user) { 27 | [self updateInterface]; 28 | } 29 | } 30 | 31 | - (void)updateInterface 32 | { 33 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 34 | paragraphStyle.lineHeightMultiple = 1.4; 35 | NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyle}; 36 | 37 | NSString *locationString = @""; 38 | if (self.user.location.length) { 39 | locationString = [NSString stringWithFormat:@"所在地:%@\n", self.user.location]; 40 | } 41 | NSString *infoString = [NSString stringWithFormat:@"%@自述:%@", locationString, self.user.desc]; 42 | 43 | self.infoLabel.attributedText = [[NSAttributedString alloc] initWithString:infoString attributes:attributes]; 44 | } 45 | 46 | - (UIStatusBarStyle)preferredStatusBarStyle 47 | { 48 | return UIStatusBarStyleLightContent; 49 | } 50 | 51 | #pragma mark - EventHandler 52 | 53 | - (IBAction)closeButtonTouchUp:(id)sender 54 | { 55 | [self dismissViewControllerAnimated:YES completion:nil]; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /fansky/Controllers/SAUserListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserListViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAUserListViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Controllers/SAUserListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserListViewController.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAUserListViewController.h" 10 | #import "SADataManager+User.h" 11 | #import "SAUserCell.h" 12 | #import "SAUser+CoreDataProperties.h" 13 | #import "SAAPIService.h" 14 | 15 | @interface SAUserListViewController () 16 | 17 | @property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController; 18 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *editButton; 19 | 20 | @end 21 | 22 | @implementation SAUserListViewController 23 | 24 | static NSString *const ENTITY_NAME = @"SAUser"; 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | 30 | [self updateInterface]; 31 | [self fetchedResultsController]; 32 | } 33 | 34 | - (void)viewDidAppear:(BOOL)animated 35 | { 36 | [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated]; 37 | [super viewDidAppear:animated]; 38 | BOOL isExist = [[SADataManager sharedManager] isLocalUserExist]; 39 | if (!isExist) { 40 | [self performSegueWithIdentifier:@"UserListToAuthNavigationSegue" sender:nil]; 41 | } 42 | } 43 | 44 | - (void)didReceiveMemoryWarning 45 | { 46 | [super didReceiveMemoryWarning]; 47 | } 48 | 49 | - (void)updateInterface 50 | { 51 | self.tableView.tableFooterView = [UIView new]; 52 | } 53 | 54 | - (IBAction)exitToUserList:(UIStoryboardSegue *)segue 55 | { 56 | 57 | } 58 | 59 | - (NSFetchedResultsController *)fetchedResultsController 60 | { 61 | if (!_fetchedResultsController) { 62 | SADataManager *manager = [SADataManager sharedManager]; 63 | 64 | NSSortDescriptor *userNameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; 65 | NSArray *sortArray = [[NSArray alloc] initWithObjects: userNameSortDescriptor, nil]; 66 | 67 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 68 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"isLocal = %@", @(YES)]; 69 | fetchRequest.sortDescriptors = sortArray; 70 | fetchRequest.returnsObjectsAsFaults = NO; 71 | fetchRequest.fetchBatchSize = 6; 72 | 73 | _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:manager.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 74 | _fetchedResultsController.delegate = self; 75 | 76 | [_fetchedResultsController performFetch:nil]; 77 | } 78 | return _fetchedResultsController; 79 | } 80 | 81 | #pragma mark - NSFetchedResultsControllerDelegate 82 | 83 | - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath 84 | { 85 | [self.tableView reloadData]; 86 | } 87 | 88 | - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type 89 | { 90 | [self.tableView reloadData]; 91 | } 92 | 93 | #pragma mark - Table view data source 94 | 95 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 96 | { 97 | return self.fetchedResultsController.sections.count; 98 | } 99 | 100 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 101 | { 102 | NSInteger numberOfItems = [[self.fetchedResultsController.sections objectAtIndex:section] numberOfObjects]; 103 | return numberOfItems; 104 | } 105 | 106 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 107 | SAUserCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SAUserCell" forIndexPath:indexPath]; 108 | if (cell) { 109 | SAUser *user = [self.fetchedResultsController objectAtIndexPath:indexPath]; 110 | [cell configWithUser:user]; 111 | } 112 | return cell; 113 | } 114 | 115 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 116 | { 117 | SAUser *user = [self.fetchedResultsController objectAtIndexPath:indexPath]; 118 | [[SAAPIService sharedSingleton] stopAllTasks]; 119 | [[SADataManager sharedManager] setCurrentUserWithUserID:user.userID]; 120 | } 121 | 122 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath 123 | { 124 | if (editingStyle == UITableViewCellEditingStyleDelete) { 125 | SAUser *user = [self.fetchedResultsController objectAtIndexPath:indexPath]; 126 | [[SADataManager sharedManager] deleteUserWithUserID:user.userID]; 127 | } 128 | } 129 | 130 | #pragma mark - EventHandler 131 | 132 | - (IBAction)addButtonTouchUp:(id)sender 133 | { 134 | [self performSegueWithIdentifier:@"UserListToAuthNavigationSegue" sender:nil]; 135 | } 136 | 137 | - (IBAction)editButtonTouchUp:(id)sender 138 | { 139 | UIBarButtonItem *editButton = (UIBarButtonItem *)sender; 140 | if ([editButton.title isEqualToString:@"编辑"]) { 141 | self.tableView.editing = YES; 142 | editButton.title = @"完成"; 143 | } else if ([editButton.title isEqualToString:@"完成"]) { 144 | self.tableView.editing = NO; 145 | editButton.title = @"编辑"; 146 | } 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /fansky/Controllers/SAUserViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserViewController.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/15/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ARSegmentPageController.h" 11 | 12 | @interface SAUserViewController : ARSegmentPageController 13 | 14 | @property (copy, nonatomic) NSString *userID; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/AppIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/AppIcon.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "size" : "29x29", 15 | "idiom" : "iphone", 16 | "filename" : "Icon58.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "size" : "29x29", 21 | "idiom" : "iphone", 22 | "filename" : "Icon87.png", 23 | "scale" : "3x" 24 | }, 25 | { 26 | "size" : "40x40", 27 | "idiom" : "iphone", 28 | "filename" : "Icon80.png", 29 | "scale" : "2x" 30 | }, 31 | { 32 | "size" : "40x40", 33 | "idiom" : "iphone", 34 | "filename" : "Icon120-1.png", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "size" : "60x60", 39 | "idiom" : "iphone", 40 | "filename" : "Icon120.png", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "size" : "60x60", 45 | "idiom" : "iphone", 46 | "filename" : "Icon180.png", 47 | "scale" : "3x" 48 | }, 49 | { 50 | "size" : "1024x1024", 51 | "idiom" : "ios-marketing", 52 | "filename" : "AppIcon.png", 53 | "scale" : "1x" 54 | } 55 | ], 56 | "info" : { 57 | "version" : 1, 58 | "author" : "xcode" 59 | } 60 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon120-1.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAccount.imageset/BackgroundAccount@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundAccount.imageset/BackgroundAccount@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAccount.imageset/BackgroundAccount@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundAccount.imageset/BackgroundAccount@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAccount.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "BackgroundAccount@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "BackgroundAccount@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAvatar.imageset/BackgroundAvatar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundAvatar.imageset/BackgroundAvatar@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAvatar.imageset/BackgroundAvatar@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundAvatar.imageset/BackgroundAvatar@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundAvatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "BackgroundAvatar@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "BackgroundAvatar@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundGrayLine.imageset/BackgroundGrayLine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundGrayLine.imageset/BackgroundGrayLine.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundGrayLine.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "resizing" : { 5 | "mode" : "9-part", 6 | "center" : { 7 | "mode" : "fill", 8 | "width" : 1, 9 | "height" : 1 10 | }, 11 | "capInsets" : { 12 | "bottom" : 1, 13 | "top" : 1, 14 | "right" : 1, 15 | "left" : 1 16 | } 17 | }, 18 | "idiom" : "universal", 19 | "filename" : "BackgroundGrayLine.png", 20 | "scale" : "1x" 21 | }, 22 | { 23 | "idiom" : "universal", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "idiom" : "universal", 28 | "scale" : "3x" 29 | } 30 | ], 31 | "info" : { 32 | "version" : 1, 33 | "author" : "xcode" 34 | } 35 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundImage.imageset/BackgroundImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/BackgroundImage.imageset/BackgroundImage.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/BackgroundImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "BackgroundImage.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/Brand Assets.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "minimum-system-version" : "7.0", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "orientation" : "portrait", 11 | "idiom" : "iphone", 12 | "minimum-system-version" : "7.0", 13 | "subtype" : "retina4", 14 | "scale" : "2x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconAt.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconAt@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconAt@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconAt.imageset/IconAt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconAt.imageset/IconAt@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconAt.imageset/IconAt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconAt.imageset/IconAt@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackBlack.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconBack@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconBack@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackBlack.imageset/IconBack@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBackBlack.imageset/IconBack@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackBlack.imageset/IconBack@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBackBlack.imageset/IconBack@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackColor.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconBackColor@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconBackColor@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackColor.imageset/IconBackColor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBackColor.imageset/IconBackColor@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBackColor.imageset/IconBackColor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBackColor.imageset/IconBackColor@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBell.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconBell@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconBell@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBell.imageset/IconBell@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBell.imageset/IconBell@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconBell.imageset/IconBell@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconBell.imageset/IconBell@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCamera.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconCamera@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconCamera@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCamera.imageset/IconCamera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCamera.imageset/IconCamera@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCamera.imageset/IconCamera@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCamera.imageset/IconCamera@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCameraCheck.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconCameraSelect@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconCameraSelect@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCameraCheck.imageset/IconCameraSelect@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCameraCheck.imageset/IconCameraSelect@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCameraCheck.imageset/IconCameraSelect@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCameraCheck.imageset/IconCameraSelect@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconClose.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconClose@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconClose@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconClose.imageset/IconClose@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconClose.imageset/IconClose@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconClose.imageset/IconClose@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconClose.imageset/IconClose@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCompose.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconCompose@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconCompose@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCompose.imageset/IconCompose@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCompose.imageset/IconCompose@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconCompose.imageset/IconCompose@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconCompose.imageset/IconCompose@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconFansky.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconFansky@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconFansky@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconFansky.imageset/IconFansky@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconFansky.imageset/IconFansky@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconFansky.imageset/IconFansky@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconFansky.imageset/IconFansky@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconGIF.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconGIF.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconGIF@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconGIF.imageset/IconGIF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconGIF.imageset/IconGIF.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconGIF.imageset/IconGIF@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconGIF.imageset/IconGIF@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconHome.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconHome@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconHome@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconHome.imageset/IconHome@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconHome.imageset/IconHome@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconHome.imageset/IconHome@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconHome.imageset/IconHome@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconLock.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconLock@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconLock@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconLock.imageset/IconLock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconLock.imageset/IconLock@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconLock.imageset/IconLock@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconLock.imageset/IconLock@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconMail.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconMessage@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconMessage@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconMail.imageset/IconMessage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconMail.imageset/IconMessage@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconMail.imageset/IconMessage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconMail.imageset/IconMessage@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconPerson.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconPerson@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconPerson@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconPerson.imageset/IconPerson@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconPerson.imageset/IconPerson@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconPerson.imageset/IconPerson@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconPerson.imageset/IconPerson@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReply.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconReply@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconReply@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReply.imageset/IconReply@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconReply.imageset/IconReply@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReply.imageset/IconReply@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconReply.imageset/IconReply@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReplySmall.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconReplySmall@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconReplySmall@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReplySmall.imageset/IconReplySmall@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconReplySmall.imageset/IconReplySmall@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconReplySmall.imageset/IconReplySmall@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconReplySmall.imageset/IconReplySmall@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepost.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconRepost@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconRepost@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepost.imageset/IconRepost@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconRepost.imageset/IconRepost@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepost.imageset/IconRepost@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconRepost.imageset/IconRepost@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepostSmall.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconRepostSmall@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconRepostSmall@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepostSmall.imageset/IconRepostSmall@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconRepostSmall.imageset/IconRepostSmall@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconRepostSmall.imageset/IconRepostSmall@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconRepostSmall.imageset/IconRepostSmall@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSearch.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconSearch@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconSearch@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSearch.imageset/IconSearch@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconSearch.imageset/IconSearch@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSearch.imageset/IconSearch@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconSearch.imageset/IconSearch@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSetting.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconSetting@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconSetting@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSetting.imageset/IconSetting@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconSetting.imageset/IconSetting@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconSetting.imageset/IconSetting@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconSetting.imageset/IconSetting@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconShareContent.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconShareContent@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconShareContent@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconShareContent.imageset/IconShareContent@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconShareContent.imageset/IconShareContent@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconShareContent.imageset/IconShareContent@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconShareContent.imageset/IconShareContent@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconStar@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconStar@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStar.imageset/IconStar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStar.imageset/IconStar@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStar.imageset/IconStar@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStar.imageset/IconStar@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStarSelected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "IconStarHover@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "IconStarHover@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStarSelected.imageset/IconStarHover@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStarSelected.imageset/IconStarHover@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStarSelected.imageset/IconStarHover@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStarSelected.imageset/IconStarHover@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStop.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "IconStop@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "IconStop@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStop.imageset/IconStop@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStop.imageset/IconStop@2x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/IconStop.imageset/IconStop@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simpleapples/fansky/5d495a86f1b8b73005861a24082f5a3daaa997e6/fansky/Images.xcassets/IconStop.imageset/IconStop@3x.png -------------------------------------------------------------------------------- /fansky/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "orientation" : "landscape", 13 | "idiom" : "iphone", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "8.0", 16 | "subtype" : "736h", 17 | "scale" : "3x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "iphone", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "8.0", 24 | "subtype" : "667h", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "orientation" : "portrait", 29 | "idiom" : "iphone", 30 | "extent" : "full-screen", 31 | "minimum-system-version" : "7.0", 32 | "scale" : "2x" 33 | }, 34 | { 35 | "orientation" : "portrait", 36 | "idiom" : "iphone", 37 | "extent" : "full-screen", 38 | "minimum-system-version" : "7.0", 39 | "subtype" : "retina4", 40 | "scale" : "2x" 41 | }, 42 | { 43 | "orientation" : "portrait", 44 | "idiom" : "iphone", 45 | "extent" : "full-screen", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "orientation" : "portrait", 50 | "idiom" : "iphone", 51 | "extent" : "full-screen", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "orientation" : "portrait", 56 | "idiom" : "iphone", 57 | "extent" : "full-screen", 58 | "subtype" : "retina4", 59 | "scale" : "2x" 60 | } 61 | ], 62 | "info" : { 63 | "version" : 1, 64 | "author" : "xcode" 65 | } 66 | } -------------------------------------------------------------------------------- /fansky/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | 饭斯基 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.6 19 | CFBundleSignature 20 | ???? 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | None 26 | CFBundleURLName 27 | com.zangzhiya.fansky 28 | CFBundleURLSchemes 29 | 30 | fansky 31 | 32 | 33 | 34 | CFBundleVersion 35 | 125 36 | Fabric 37 | 38 | APIKey 39 | bf1bdc051ce5990b8445d157bdf2ab47e59adfb2 40 | Kits 41 | 42 | 43 | KitInfo 44 | 45 | KitName 46 | Crashlytics 47 | 48 | 49 | 50 | ITSAppUsesNonExemptEncryption 51 | 52 | LSRequiresIPhoneOS 53 | 54 | NSAppTransportSecurity 55 | 56 | NSAllowsArbitraryLoads 57 | 58 | 59 | NSCameraUsageDescription 60 | 饭斯基想使用您的摄像头 61 | NSPhotoLibraryUsageDescription 62 | 饭斯基想读取您的相册 63 | UIApplicationShortcutItems 64 | 65 | 66 | UIApplicationShortcutItemIconType 67 | UIApplicationShortcutIconTypeSearch 68 | UIApplicationShortcutItemTitle 69 | 搜索 70 | UIApplicationShortcutItemType 71 | com.zangzhiya.fansky.search 72 | 73 | 74 | UIApplicationShortcutItemIconType 75 | UIApplicationShortcutIconTypeCompose 76 | UIApplicationShortcutItemTitle 77 | 发饭 78 | UIApplicationShortcutItemType 79 | com.zangzhiya.fansky.compose 80 | 81 | 82 | UILaunchStoryboardName 83 | LaunchScreen 84 | UIMainStoryboardFile 85 | SAMain 86 | UIRequiredDeviceCapabilities 87 | 88 | armv7 89 | 90 | UIStatusBarHidden 91 | 92 | UIStatusBarStyle 93 | UIStatusBarStyleDefault 94 | UISupportedInterfaceOrientations 95 | 96 | UIInterfaceOrientationPortrait 97 | 98 | UIViewControllerBasedStatusBarAppearance 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /fansky/Models/SAConversation+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversation+CoreDataProperties.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAConversation.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAConversation (CoreDataProperties) 17 | 18 | @property (nullable, nonatomic, retain) NSNumber *count; 19 | @property (nullable, nonatomic, retain) NSNumber *isNew; 20 | @property (nullable, nonatomic, retain) NSString *otherUserID; 21 | @property (nullable, nonatomic, retain) SAUser *localUser; 22 | @property (nullable, nonatomic, retain) SAMessage *message; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /fansky/Models/SAConversation+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversation+CoreDataProperties.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAConversation+CoreDataProperties.h" 13 | 14 | @implementation SAConversation (CoreDataProperties) 15 | 16 | @dynamic count; 17 | @dynamic isNew; 18 | @dynamic otherUserID; 19 | @dynamic localUser; 20 | @dynamic message; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /fansky/Models/SAConversation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversation.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class SAMessage, SAUser; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAConversation : NSManagedObject 17 | 18 | // Insert code here to declare functionality of your managed object subclass 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | 24 | #import "SAConversation+CoreDataProperties.h" 25 | -------------------------------------------------------------------------------- /fansky/Models/SAConversation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversation.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAConversation.h" 10 | #import "SAMessage.h" 11 | #import "SAUser.h" 12 | 13 | @implementation SAConversation 14 | 15 | // Insert code here to add functionality to your managed object subclass 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Models/SAFriend.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAFriend.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAFriend : NSObject 12 | 13 | @property (copy, nonatomic, readonly) NSString *friendID; 14 | @property (copy, nonatomic, readonly) NSString *name; 15 | @property (copy, nonatomic, readonly) NSString *profileImageURL; 16 | @property (strong, nonatomic) NSNumber *following; 17 | 18 | - (instancetype)initWithObject:(id)object; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /fansky/Models/SAFriend.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAFriend.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAFriend.h" 10 | 11 | @interface SAFriend () 12 | 13 | @property (copy, nonatomic, readwrite) NSString *friendID; 14 | @property (copy, nonatomic, readwrite) NSString *name; 15 | @property (copy, nonatomic, readwrite) NSString *profileImageURL; 16 | 17 | @end 18 | 19 | @implementation SAFriend 20 | 21 | - (instancetype)init 22 | { 23 | @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must use initWithObject: instead." userInfo:nil]; 24 | } 25 | 26 | - (instancetype)initWithObject:(id)object 27 | { 28 | self = [super init]; 29 | if (self) { 30 | self.friendID = (NSString *)[object objectForKey:@"id"]; 31 | self.name = (NSString *)[object objectForKey:@"name"]; 32 | self.profileImageURL = (NSString *)[object objectForKey:@"profile_image_url"]; 33 | self.following = (NSNumber *)[object objectForKey:@"following"]; 34 | } 35 | return self; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /fansky/Models/SAMessage+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessage+CoreDataProperties.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAMessage.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAMessage (CoreDataProperties) 17 | 18 | @property (nullable, nonatomic, retain) NSDate *createdAt; 19 | @property (nullable, nonatomic, retain) NSString *messageID; 20 | @property (nullable, nonatomic, retain) NSString *recipientID; 21 | @property (nullable, nonatomic, retain) NSString *senderID; 22 | @property (nullable, nonatomic, retain) NSString *text; 23 | @property (nullable, nonatomic, retain) NSSet *conversations; 24 | @property (nullable, nonatomic, retain) NSSet *localUsers; 25 | @property (nullable, nonatomic, retain) SAUser *recipient; 26 | @property (nullable, nonatomic, retain) SAUser *sender; 27 | 28 | @end 29 | 30 | @interface SAMessage (CoreDataGeneratedAccessors) 31 | 32 | - (void)addConversationsObject:(SAConversation *)value; 33 | - (void)removeConversationsObject:(SAConversation *)value; 34 | - (void)addConversations:(NSSet *)values; 35 | - (void)removeConversations:(NSSet *)values; 36 | 37 | - (void)addLocalUsersObject:(SAUser *)value; 38 | - (void)removeLocalUsersObject:(SAUser *)value; 39 | - (void)addLocalUsers:(NSSet *)values; 40 | - (void)removeLocalUsers:(NSSet *)values; 41 | 42 | @end 43 | 44 | NS_ASSUME_NONNULL_END 45 | -------------------------------------------------------------------------------- /fansky/Models/SAMessage+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessage+CoreDataProperties.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAMessage+CoreDataProperties.h" 13 | 14 | @implementation SAMessage (CoreDataProperties) 15 | 16 | @dynamic createdAt; 17 | @dynamic messageID; 18 | @dynamic recipientID; 19 | @dynamic senderID; 20 | @dynamic text; 21 | @dynamic conversations; 22 | @dynamic localUsers; 23 | @dynamic recipient; 24 | @dynamic sender; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /fansky/Models/SAMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessage.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class SAConversation, SAUser; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAMessage : NSManagedObject 17 | 18 | // Insert code here to declare functionality of your managed object subclass 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | 24 | #import "SAMessage+CoreDataProperties.h" 25 | -------------------------------------------------------------------------------- /fansky/Models/SAMessage.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessage.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAMessage.h" 10 | #import "SAConversation.h" 11 | #import "SAUser.h" 12 | 13 | @implementation SAMessage 14 | 15 | // Insert code here to add functionality to your managed object subclass 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Models/SAPhoto+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhoto+CoreDataProperties.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAPhoto.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAPhoto (CoreDataProperties) 17 | 18 | @property (nullable, nonatomic, retain) NSString *imageURL; 19 | @property (nullable, nonatomic, retain) NSString *largeURL; 20 | @property (nullable, nonatomic, retain) NSString *photoURL; 21 | @property (nullable, nonatomic, retain) NSString *statusID; 22 | @property (nullable, nonatomic, retain) NSString *thumbURL; 23 | @property (nullable, nonatomic, retain) SAStatus *status; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /fansky/Models/SAPhoto+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhoto+CoreDataProperties.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAPhoto+CoreDataProperties.h" 13 | 14 | @implementation SAPhoto (CoreDataProperties) 15 | 16 | @dynamic imageURL; 17 | @dynamic largeURL; 18 | @dynamic photoURL; 19 | @dynamic statusID; 20 | @dynamic thumbURL; 21 | @dynamic status; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /fansky/Models/SAPhoto.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhoto.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class SAStatus; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAPhoto : NSManagedObject 17 | 18 | // Insert code here to declare functionality of your managed object subclass 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | 24 | #import "SAPhoto+CoreDataProperties.h" 25 | -------------------------------------------------------------------------------- /fansky/Models/SAPhoto.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhoto.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAPhoto.h" 10 | #import "SAStatus.h" 11 | 12 | @implementation SAPhoto 13 | 14 | // Insert code here to add functionality to your managed object subclass 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/Models/SAStatus+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStatus+CoreDataProperties.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAStatus.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAStatus (CoreDataProperties) 17 | 18 | @property (nullable, nonatomic, retain) NSDate *createdAt; 19 | @property (nullable, nonatomic, retain) NSNumber *isFavorited; 20 | @property (nullable, nonatomic, retain) NSString *replyStatusID; 21 | @property (nullable, nonatomic, retain) NSString *repostStatusID; 22 | @property (nullable, nonatomic, retain) NSString *source; 23 | @property (nullable, nonatomic, retain) NSString *statusID; 24 | @property (nullable, nonatomic, retain) NSString *text; 25 | @property (nullable, nonatomic, retain) NSNumber *type; 26 | @property (nullable, nonatomic, retain) NSSet *localUsers; 27 | @property (nullable, nonatomic, retain) SAPhoto *photo; 28 | @property (nullable, nonatomic, retain) SAUser *user; 29 | 30 | @end 31 | 32 | @interface SAStatus (CoreDataGeneratedAccessors) 33 | 34 | - (void)addLocalUsersObject:(SAUser *)value; 35 | - (void)removeLocalUsersObject:(SAUser *)value; 36 | - (void)addLocalUsers:(NSSet *)values; 37 | - (void)removeLocalUsers:(NSSet *)values; 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /fansky/Models/SAStatus+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAStatus+CoreDataProperties.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAStatus+CoreDataProperties.h" 13 | 14 | @implementation SAStatus (CoreDataProperties) 15 | 16 | @dynamic createdAt; 17 | @dynamic isFavorited; 18 | @dynamic replyStatusID; 19 | @dynamic repostStatusID; 20 | @dynamic source; 21 | @dynamic statusID; 22 | @dynamic text; 23 | @dynamic type; 24 | @dynamic localUsers; 25 | @dynamic photo; 26 | @dynamic user; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /fansky/Models/SAStatus.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStatus.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_OPTIONS(NSUInteger, SAStatusTypes) 13 | { 14 | SAStatusTypeTimeLine = 1 << 0, 15 | 16 | SAStatusTypeUserStatus = 1 << 1, 17 | 18 | SAStatusTypeMentionStatus = 1 << 2, 19 | 20 | SAStatusTypeFavoriteStatus = 1 << 3 21 | }; 22 | 23 | @class SAPhoto, SAUser; 24 | 25 | NS_ASSUME_NONNULL_BEGIN 26 | 27 | @interface SAStatus : NSManagedObject 28 | 29 | // Insert code here to declare functionality of your managed object subclass 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | 35 | #import "SAStatus+CoreDataProperties.h" 36 | -------------------------------------------------------------------------------- /fansky/Models/SAStatus.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAStatus.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAStatus.h" 10 | #import "SAPhoto.h" 11 | #import "SAUser.h" 12 | 13 | @implementation SAStatus 14 | 15 | // Insert code here to add functionality to your managed object subclass 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Models/SATrend.h: -------------------------------------------------------------------------------- 1 | // 2 | // SATrend.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/16. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SATrend : NSObject 12 | 13 | @property (copy, nonatomic, readonly) NSString *name; 14 | @property (copy, nonatomic, readonly) NSString *query; 15 | @property (copy, nonatomic, readonly) NSString *url; 16 | 17 | - (instancetype)initWithObject:(id)object; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /fansky/Models/SATrend.m: -------------------------------------------------------------------------------- 1 | // 2 | // SATrend.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/16. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SATrend.h" 10 | 11 | @interface SATrend () 12 | 13 | @property (copy, nonatomic, readwrite) NSString *name; 14 | @property (copy, nonatomic, readwrite) NSString *query; 15 | @property (copy, nonatomic, readwrite) NSString *url; 16 | 17 | @end 18 | 19 | @implementation SATrend 20 | 21 | - (instancetype)init 22 | { 23 | @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must use initWithObject: instead." userInfo:nil]; 24 | } 25 | 26 | - (instancetype)initWithObject:(id)object 27 | { 28 | self = [super init]; 29 | if (self) { 30 | self.name = [object objectForKey:@"name"]; 31 | self.query = [object objectForKey:@"query"]; 32 | self.url = [object objectForKey:@"url"]; 33 | } 34 | return self; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /fansky/Models/SAUser+CoreDataProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUser+CoreDataProperties.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAUser.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAUser (CoreDataProperties) 17 | 18 | @property (nullable, nonatomic, retain) NSString *desc; 19 | @property (nullable, nonatomic, retain) NSNumber *followersCount; 20 | @property (nullable, nonatomic, retain) NSNumber *friendsCount; 21 | @property (nullable, nonatomic, retain) NSNumber *isActive; 22 | @property (nullable, nonatomic, retain) NSNumber *isFollowing; 23 | @property (nullable, nonatomic, retain) NSNumber *isLocal; 24 | @property (nullable, nonatomic, retain) NSNumber *isProtected; 25 | @property (nullable, nonatomic, retain) NSString *location; 26 | @property (nullable, nonatomic, retain) NSString *name; 27 | @property (nullable, nonatomic, retain) NSString *profileImageURL; 28 | @property (nullable, nonatomic, retain) NSNumber *statusCount; 29 | @property (nullable, nonatomic, retain) NSString *token; 30 | @property (nullable, nonatomic, retain) NSString *tokenSecret; 31 | @property (nullable, nonatomic, retain) NSString *userID; 32 | @property (nullable, nonatomic, retain) NSDate *createdAt; 33 | @property (nullable, nonatomic, retain) NSSet *mineConversations; 34 | @property (nullable, nonatomic, retain) NSSet *mineMessages; 35 | @property (nullable, nonatomic, retain) NSSet *mineStatuses; 36 | @property (nullable, nonatomic, retain) NSSet *recvivedMessages; 37 | @property (nullable, nonatomic, retain) NSSet *sentMessages; 38 | @property (nullable, nonatomic, retain) NSSet *statuses; 39 | 40 | @end 41 | 42 | @interface SAUser (CoreDataGeneratedAccessors) 43 | 44 | - (void)addMineConversationsObject:(SAConversation *)value; 45 | - (void)removeMineConversationsObject:(SAConversation *)value; 46 | - (void)addMineConversations:(NSSet *)values; 47 | - (void)removeMineConversations:(NSSet *)values; 48 | 49 | - (void)addMineMessagesObject:(SAMessage *)value; 50 | - (void)removeMineMessagesObject:(SAMessage *)value; 51 | - (void)addMineMessages:(NSSet *)values; 52 | - (void)removeMineMessages:(NSSet *)values; 53 | 54 | - (void)addMineStatusesObject:(SAStatus *)value; 55 | - (void)removeMineStatusesObject:(SAStatus *)value; 56 | - (void)addMineStatuses:(NSSet *)values; 57 | - (void)removeMineStatuses:(NSSet *)values; 58 | 59 | - (void)addRecvivedMessagesObject:(SAMessage *)value; 60 | - (void)removeRecvivedMessagesObject:(SAMessage *)value; 61 | - (void)addRecvivedMessages:(NSSet *)values; 62 | - (void)removeRecvivedMessages:(NSSet *)values; 63 | 64 | - (void)addSentMessagesObject:(SAMessage *)value; 65 | - (void)removeSentMessagesObject:(SAMessage *)value; 66 | - (void)addSentMessages:(NSSet *)values; 67 | - (void)removeSentMessages:(NSSet *)values; 68 | 69 | - (void)addStatusesObject:(SAStatus *)value; 70 | - (void)removeStatusesObject:(SAStatus *)value; 71 | - (void)addStatuses:(NSSet *)values; 72 | - (void)removeStatuses:(NSSet *)values; 73 | 74 | @end 75 | 76 | NS_ASSUME_NONNULL_END 77 | -------------------------------------------------------------------------------- /fansky/Models/SAUser+CoreDataProperties.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAUser+CoreDataProperties.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/23. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | // Choose "Create NSManagedObject Subclass…" from the Core Data editor menu 9 | // to delete and recreate this implementation file for your updated model. 10 | // 11 | 12 | #import "SAUser+CoreDataProperties.h" 13 | 14 | @implementation SAUser (CoreDataProperties) 15 | 16 | @dynamic desc; 17 | @dynamic followersCount; 18 | @dynamic friendsCount; 19 | @dynamic isActive; 20 | @dynamic isFollowing; 21 | @dynamic isLocal; 22 | @dynamic isProtected; 23 | @dynamic location; 24 | @dynamic name; 25 | @dynamic profileImageURL; 26 | @dynamic statusCount; 27 | @dynamic token; 28 | @dynamic tokenSecret; 29 | @dynamic userID; 30 | @dynamic createdAt; 31 | @dynamic mineConversations; 32 | @dynamic mineMessages; 33 | @dynamic mineStatuses; 34 | @dynamic recvivedMessages; 35 | @dynamic sentMessages; 36 | @dynamic statuses; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /fansky/Models/SAUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUser.h 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class SAConversation, SAMessage, SAStatus; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface SAUser : NSManagedObject 17 | 18 | // Insert code here to declare functionality of your managed object subclass 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | 24 | #import "SAUser+CoreDataProperties.h" 25 | -------------------------------------------------------------------------------- /fansky/Models/SAUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAUser.m 3 | // fansky 4 | // 5 | // Created by Zzy on 10/7/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAUser.h" 10 | #import "SAConversation.h" 11 | #import "SAMessage.h" 12 | #import "SAStatus.h" 13 | 14 | @implementation SAUser 15 | 16 | // Insert code here to add functionality to your managed object subclass 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/SAAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // fansky 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SAAppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/SAConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConstants.h 3 | // fansky 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | FOUNDATION_EXPORT BOOL SA_DEBUG; 12 | 13 | FOUNDATION_EXPORT NSString *const SA_APP_DOMAIN; 14 | 15 | FOUNDATION_EXPORT NSString *const SA_API_BASE_HOST; 16 | FOUNDATION_EXPORT NSString *const SA_API_COMSUMER_KEY; 17 | FOUNDATION_EXPORT NSString *const SA_API_COMSUMER_SECRET; 18 | FOUNDATION_EXPORT NSString *const SA_API_ACCESS_TOKEN_PATH; 19 | FOUNDATION_EXPORT NSString *const SA_API_REQUEST_TOKEN_PATH; 20 | FOUNDATION_EXPORT NSString *const SA_API_AUTHORIZE_PATH; 21 | FOUNDATION_EXPORT NSString *const SA_API_AUTHORIZE_CALLBACK_URL; 22 | 23 | FOUNDATION_EXPORT NSString *const SA_API_HOST; 24 | FOUNDATION_EXPORT NSString *const SA_API_VERIFY_CREDENTIALS_PATH; 25 | FOUNDATION_EXPORT NSString *const SA_API_ACCOUNT_NOTIFICATION_PATH; 26 | FOUNDATION_EXPORT NSString *const SA_API_UPDATE_PROFILE_IMAGE_PATH; 27 | FOUNDATION_EXPORT NSString *const SA_API_UPDATE_PROFILE_PATH; 28 | 29 | FOUNDATION_EXPORT NSString *const SA_API_HOME_TIMELINE_PATH; 30 | FOUNDATION_EXPORT NSString *const SA_API_USER_TIMELINE_PATH; 31 | FOUNDATION_EXPORT NSString *const SA_API_PUBLIC_TIMELINE_PATH; 32 | FOUNDATION_EXPORT NSString *const SA_API_UPDATE_STATUS_PATH; 33 | FOUNDATION_EXPORT NSString *const SA_API_UPDATE_PHOTO_STATUS_PATH; 34 | FOUNDATION_EXPORT NSString *const SA_API_USER_PHOTO_TIMELINE_PATH; 35 | FOUNDATION_EXPORT NSString *const SA_API_DELETE_STATUS_PATH; 36 | FOUNDATION_EXPORT NSString *const SA_API_MENTION_STATUS_PATH; 37 | FOUNDATION_EXPORT NSString *const SA_API_FAVORITE_STATUS_PATH; 38 | FOUNDATION_EXPORT NSString *const SA_API_FAVORITE_STATUS_CREATE_PATH; 39 | FOUNDATION_EXPORT NSString *const SA_API_FAVORITE_STATUS_DELETE_PATH; 40 | FOUNDATION_EXPORT NSString *const SA_API_STATUS_SHOW_PATH; 41 | 42 | FOUNDATION_EXPORT NSString *const SA_API_USER_SHOW_PATH; 43 | FOUNDATION_EXPORT NSString *const SA_API_FOLLOW_USER_PATH; 44 | FOUNDATION_EXPORT NSString *const SA_API_UNFOLLOW_USER_PATH; 45 | FOUNDATION_EXPORT NSString *const SA_API_USER_FRIEND_PATH; 46 | FOUNDATION_EXPORT NSString *const SA_API_USER_FOLLOWER_PATH; 47 | FOUNDATION_EXPORT NSString *const SA_API_FRIENDSHIP_REQUEST_PATH; 48 | FOUNDATION_EXPORT NSString *const SA_API_FRIENDSHIP_DENY_PATH; 49 | FOUNDATION_EXPORT NSString *const SA_API_FRIENDSHIP_ACCEPT_PATH; 50 | 51 | FOUNDATION_EXPORT NSString *const SA_API_CONVERSATION_LIST_PATH; 52 | FOUNDATION_EXPORT NSString *const SA_API_CONVERSATION_PATH; 53 | FOUNDATION_EXPORT NSString *const SA_API_SEND_NEW_MESSAGE_PATH; 54 | 55 | FOUNDATION_EXPORT NSString *const SA_API_SEARCH_PUBLIC_TIMELINE_PATH; 56 | 57 | FOUNDATION_EXPORT NSString *const SA_API_TRENDS_LIST_PATH; -------------------------------------------------------------------------------- /fansky/SAConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAConstants.m 3 | // fansky 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAConstants.h" 10 | 11 | #ifdef DEBUG 12 | BOOL SA_DEBUG = DEBUG; 13 | #else 14 | BOOL SA_DEBUG = NO; 15 | #endif 16 | 17 | NSString *const SA_APP_DOMAIN = @"com.zangzhiya.fansky"; 18 | 19 | NSString *const SA_API_BASE_HOST = @"fanfou.com"; 20 | NSString *const SA_API_COMSUMER_KEY = @"f1a7f5a8dc2faa0342bb8121de2f9b07"; 21 | NSString *const SA_API_COMSUMER_SECRET = @"6763155636ac7029f91cc7691d0e7939"; 22 | NSString *const SA_API_ACCESS_TOKEN_PATH = @"/oauth/access_token"; 23 | NSString *const SA_API_REQUEST_TOKEN_PATH = @"/oauth/request_token"; 24 | NSString *const SA_API_AUTHORIZE_PATH = @"/oauth/authorize"; 25 | NSString *const SA_API_AUTHORIZE_CALLBACK_URL = @"fansky://authorize-success"; 26 | 27 | NSString *const SA_API_HOST = @"api.fanfou.com"; 28 | NSString *const SA_API_VERIFY_CREDENTIALS_PATH = @"/account/verify_credentials.json"; 29 | NSString *const SA_API_ACCOUNT_NOTIFICATION_PATH = @"/account/notification.json"; 30 | NSString *const SA_API_UPDATE_PROFILE_IMAGE_PATH = @"/account/update_profile_image.json"; 31 | NSString *const SA_API_UPDATE_PROFILE_PATH = @"/account/update_profile.json"; 32 | 33 | NSString *const SA_API_HOME_TIMELINE_PATH = @"/statuses/home_timeline.json"; 34 | NSString *const SA_API_USER_TIMELINE_PATH = @"/statuses/user_timeline.json"; 35 | NSString *const SA_API_PUBLIC_TIMELINE_PATH = @"/statuses/public_timeline.json"; 36 | NSString *const SA_API_UPDATE_STATUS_PATH = @"/statuses/update.json"; 37 | NSString *const SA_API_UPDATE_PHOTO_STATUS_PATH = @"/photos/upload.json"; 38 | NSString *const SA_API_USER_PHOTO_TIMELINE_PATH = @"/photos/user_timeline.json"; 39 | NSString *const SA_API_DELETE_STATUS_PATH = @"/statuses/destroy.json"; 40 | NSString *const SA_API_MENTION_STATUS_PATH = @"/statuses/mentions.json"; 41 | NSString *const SA_API_FAVORITE_STATUS_PATH = @"/favorites/list.json"; 42 | NSString *const SA_API_FAVORITE_STATUS_CREATE_PATH = @"/favorites/create/id.json"; 43 | NSString *const SA_API_FAVORITE_STATUS_DELETE_PATH = @"/favorites/destroy/id.json"; 44 | NSString *const SA_API_STATUS_SHOW_PATH = @"/statuses/show.json"; 45 | 46 | NSString *const SA_API_USER_SHOW_PATH = @"/users/show.json"; 47 | NSString *const SA_API_FOLLOW_USER_PATH = @"/friendships/create.json"; 48 | NSString *const SA_API_UNFOLLOW_USER_PATH = @"/friendships/destroy.json"; 49 | NSString *const SA_API_USER_FRIEND_PATH = @"/users/friends.json"; 50 | NSString *const SA_API_USER_FOLLOWER_PATH = @"/users/followers.json"; 51 | NSString *const SA_API_FRIENDSHIP_REQUEST_PATH = @"/friendships/requests.json"; 52 | NSString *const SA_API_FRIENDSHIP_DENY_PATH = @"/friendships/deny.json"; 53 | NSString *const SA_API_FRIENDSHIP_ACCEPT_PATH = @"/friendships/accept.json"; 54 | 55 | NSString *const SA_API_CONVERSATION_LIST_PATH = @"/direct_messages/conversation_list.json"; 56 | NSString *const SA_API_CONVERSATION_PATH = @"/direct_messages/conversation.json"; 57 | NSString *const SA_API_SEND_NEW_MESSAGE_PATH = @"/direct_messages/new.json"; 58 | 59 | NSString *const SA_API_SEARCH_PUBLIC_TIMELINE_PATH = @"/search/public_timeline.json"; 60 | 61 | NSString *const SA_API_TRENDS_LIST_PATH = @"/trends/list.json"; 62 | -------------------------------------------------------------------------------- /fansky/Segues/SADismissAnimator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADismissAnimator.h 3 | // fansky 4 | // 5 | // Created by Zzy on 2/16/17. 6 | // Copyright © 2017 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SADismissAnimator : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fansky/Segues/SADismissAnimator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADismissAnimator.m 3 | // fansky 4 | // 5 | // Created by Zzy on 2/16/17. 6 | // Copyright © 2017 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADismissAnimator.h" 10 | #import "SAUserInfoViewController.h" 11 | 12 | @implementation SADismissAnimator 13 | 14 | -(NSTimeInterval)transitionDuration:(id)transitionContext { 15 | return 0.3; 16 | } 17 | 18 | -(void)animateTransition:(id)transitionContext { 19 | SAUserInfoViewController *sourceViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 20 | 21 | UIView *container = [transitionContext containerView]; 22 | UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; 23 | [container addSubview:toView]; 24 | 25 | [UIView animateWithDuration:0.3 animations:^{ 26 | sourceViewController.blurView.effect = nil; 27 | sourceViewController.infoLabel.alpha = 0; 28 | sourceViewController.closeButton.alpha = 0; 29 | } completion:^(BOOL finished) { 30 | [transitionContext completeTransition:finished]; 31 | }]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /fansky/Segues/SAPresentationAnimator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPresentationAnimator.h 3 | // fansky 4 | // 5 | // Created by Zzy on 2/16/17. 6 | // Copyright © 2017 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SAPresentationAnimator : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fansky/Segues/SAPresentationAnimator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPresentationAnimator.m 3 | // fansky 4 | // 5 | // Created by Zzy on 2/16/17. 6 | // Copyright © 2017 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAPresentationAnimator.h" 10 | #import "SAUserInfoViewController.h" 11 | 12 | @implementation SAPresentationAnimator 13 | 14 | -(NSTimeInterval)transitionDuration:(id)transitionContext { 15 | return 0.3; 16 | } 17 | 18 | -(void)animateTransition:(id)transitionContext { 19 | SAUserInfoViewController *destinationViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 20 | 21 | destinationViewController.blurView.effect = nil; 22 | destinationViewController.infoLabel.alpha = 0; 23 | destinationViewController.closeButton.alpha = 0; 24 | 25 | UIView *container = [transitionContext containerView]; 26 | [container addSubview:destinationViewController.view]; 27 | 28 | [UIView animateWithDuration:0.3 animations:^{ 29 | destinationViewController.blurView.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; 30 | destinationViewController.infoLabel.alpha = 1; 31 | destinationViewController.closeButton.alpha = 1; 32 | } completion:^(BOOL finished) { 33 | [transitionContext completeTransition:finished]; 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /fansky/Segues/SAPushWithoutAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPushWithoutAnimation.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/23/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAPushWithoutAnimation : UIStoryboardSegue 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /fansky/Segues/SAPushWithoutAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPushWithoutAnimation.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/23/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAPushWithoutAnimation.h" 10 | 11 | @implementation SAPushWithoutAnimation 12 | 13 | - (void)perform 14 | { 15 | UIViewController *sourceViewController = self.sourceViewController; 16 | UIViewController *destinationViewController = self.destinationViewController; 17 | 18 | [sourceViewController.navigationController pushViewController:destinationViewController animated:NO]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /fansky/Services/SAAPIService.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAAPIService.h 3 | // fansky 4 | // 5 | // Created by Zzy on 6/23/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAAPIService : NSObject 12 | 13 | + (SAAPIService *)sharedSingleton; 14 | 15 | #pragma mark - Account 16 | 17 | - (void)authorizeWithUsername:(NSString *)username password:(NSString *)password success:(void(^)(NSString *token, NSString *secret))success failure:(void(^)(NSString *error))failure; 18 | 19 | - (void)verifyCredentialsWithToken:(NSString *)token secret:(NSString *)secret success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 20 | 21 | - (void)accountNotificationWithSuccess:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 22 | 23 | - (void)updateProfileWithImage:(NSData *)image success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 24 | 25 | - (void)updateProfileWithLocation:(NSString *)location desc:(NSString *)desc success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 26 | 27 | #pragma mark - User 28 | 29 | - (void)userWithID:(NSString *)userID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 30 | 31 | - (void)followUserWithID:(NSString *)userID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 32 | 33 | - (void)unfollowUserWithID:(NSString *)userID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 34 | 35 | - (void)userFriendsWithUserID:(NSString *)userID count:(NSUInteger)count page:(NSUInteger)page success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 36 | 37 | - (void)userFollowersWithUserID:(NSString *)userID count:(NSUInteger)count page:(NSUInteger)page success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 38 | 39 | - (void)userFriendshipRequestWithCount:(NSUInteger)count page:(NSUInteger)page success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 40 | 41 | - (void)userFriendshipAcceptWithUserID:(NSString *)userID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 42 | 43 | - (void)userFriendshipDenyWithUserID:(NSString *)userID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 44 | 45 | #pragma mark - Status 46 | 47 | - (void)timeLineWithUserID:(NSString *)userID sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 48 | 49 | - (void)userTimeLineWithUserID:(NSString *)userID sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 50 | 51 | - (void)publicTimeLineWithSinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 52 | 53 | - (void)sendStatus:(NSString *)status replyToStatusID:(NSString *)replyToStatusID repostStatusID:(NSString *)repostStatusID image:(NSData *)image success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 54 | 55 | - (void)userPhotoTimeLineWithUserID:(NSString *)userID sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 56 | 57 | - (void)deleteStatusWithID:(NSString *)statusID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 58 | 59 | - (void)mentionStatusWithSinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 60 | 61 | - (void)userFavoriteTimeLineWithUserID:(NSString *)userID count:(NSUInteger)count page:(NSUInteger)page success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 62 | 63 | - (void)createFavoriteStatusWithID:(NSString *)statusID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 64 | 65 | - (void)deleteFavoriteStatusWithID:(NSString *)statusID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 66 | 67 | - (void)showStatusWithID:(NSString *)statusID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 68 | 69 | #pragma mark - Message 70 | 71 | - (void)conversationListWithCount:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 72 | 73 | - (void)conversationWithUserID:(NSString *)userID sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 74 | 75 | - (void)sendMessageWithUserID:(NSString *)userID text:(NSString *)text replyToMessageID:(NSString *)replyToMessageID success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 76 | 77 | #pragma mark - Search 78 | 79 | - (void)searchPublicTimeLineWithKeyword:(NSString *)keyword sinceID:(NSString *)sinceID maxID:(NSString *)maxID count:(NSInteger)count success:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 80 | 81 | #pragma mark - Trend 82 | 83 | - (void)trendsWithSuccess:(void(^)(id data))success failure:(void(^)(NSString *error))failure; 84 | 85 | #pragma mark - Base 86 | 87 | - (void)stopAllTasks; 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /fansky/Services/SACacheManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SACacheManager.h 3 | // fansky 4 | // 5 | // Created by Zzy on 11/12/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SACacheManager : NSObject 12 | 13 | + (SACacheManager *)sharedManager; 14 | 15 | - (void)cacheItem:(id)item forKey:(NSString *)key; 16 | - cachedItemForKey:(NSString *)key; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/Services/SACacheManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SACacheManager.m 3 | // fansky 4 | // 5 | // Created by Zzy on 11/12/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SACacheManager.h" 10 | 11 | @interface SACacheManager () 12 | 13 | @property (strong, nonatomic) NSMutableDictionary *cacheDictionary; 14 | 15 | @end 16 | 17 | @implementation SACacheManager 18 | 19 | + (SACacheManager *)sharedManager 20 | { 21 | static SACacheManager *sharedManager; 22 | static dispatch_once_t token = 0; 23 | dispatch_once(&token, ^{ 24 | if (!sharedManager) { 25 | sharedManager = [[SACacheManager alloc] init]; 26 | } 27 | }); 28 | return sharedManager; 29 | } 30 | 31 | - (instancetype)init 32 | { 33 | self = [super init]; 34 | if (self) { 35 | self.cacheDictionary = [[NSMutableDictionary alloc] init]; 36 | } 37 | return self; 38 | } 39 | 40 | - (id)cachedItemForKey:(NSString *)key 41 | { 42 | return [self.cacheDictionary valueForKey:key]; 43 | } 44 | 45 | - (void)cacheItem:(id)item forKey:(NSString *)key 46 | { 47 | [self.cacheDictionary setValue:item forKey:key]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Conversation.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Conversation.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | 11 | @class SAUser; 12 | @class SAConversation; 13 | 14 | @interface SADataManager (Conversation) 15 | 16 | - (void)insertOrUpdateConversationsWithObjects:(id)objects; 17 | - (SAConversation *)insertOrUpdateConversationWithObject:(id)object localUser:(SAUser *)localUser; 18 | - (SAConversation *)conversationWithOtherUserID:(NSString *)otherUserID localUser:(SAUser *)localUser; 19 | - (NSArray *)currentConversationListWithUserID:(NSString *)userID limit:(NSUInteger)limit; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Conversation.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Conversation.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager+Conversation.h" 10 | #import "SADataManager+User.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import "SADataManager+Message.h" 13 | #import "SAConversation+CoreDataProperties.h" 14 | 15 | #import "SAMessage+CoreDataProperties.h" 16 | 17 | @implementation SADataManager (Conversation) 18 | 19 | static NSString *const ENTITY_NAME = @"SAConversation"; 20 | 21 | - (void)insertOrUpdateConversationsWithObjects:(id)objects 22 | { 23 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 24 | [objects enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop) { 25 | [self insertOrUpdateConversationWithObject:object localUser:currentUser]; 26 | }]; 27 | } 28 | 29 | - (SAConversation *)insertOrUpdateConversationWithObject:(id)object localUser:(SAUser *)localUser 30 | { 31 | NSString *otherUserID = [object objectForKey:@"otherid"]; 32 | NSNumber *count = [object objectForKey:@"msg_num"]; 33 | NSNumber *isNew = [object objectForKey:@"new_conv"]; 34 | 35 | SAMessage *message = [[SADataManager sharedManager] insertOrUpdateMessageWithObject:[object objectForKey:@"dm"] localUser:localUser]; 36 | 37 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 38 | fetchRequest.fetchLimit = 1; 39 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"otherUserID = %@", otherUserID]; 40 | 41 | __block NSError *error; 42 | __block SAConversation *resultConversation; 43 | [self.managedObjectContext performBlockAndWait:^{ 44 | NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 45 | if (!error && fetchResult && fetchResult.count) { 46 | SAConversation *existConversation = [fetchResult firstObject]; 47 | existConversation.otherUserID = otherUserID; 48 | existConversation.count = count; 49 | existConversation.isNew = isNew; 50 | existConversation.message = message; 51 | existConversation.localUser = localUser; 52 | resultConversation = existConversation; 53 | } else { 54 | [self.managedObjectContext performBlockAndWait:^{ 55 | SAConversation *conversation = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NAME inManagedObjectContext:self.managedObjectContext]; 56 | conversation.otherUserID = otherUserID; 57 | conversation.count = count; 58 | conversation.isNew = isNew; 59 | conversation.message = message; 60 | conversation.localUser = localUser; 61 | resultConversation = conversation; 62 | }]; 63 | } 64 | }]; 65 | return resultConversation; 66 | } 67 | 68 | - (SAConversation *)conversationWithOtherUserID:(NSString *)otherUserID localUser:(SAUser *)localUser 69 | { 70 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 71 | fetchRequest.fetchLimit = 1; 72 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"otherUserID = %@", otherUserID]; 73 | 74 | __block NSError *error; 75 | __block SAConversation *resultConversation; 76 | [self.managedObjectContext performBlockAndWait:^{ 77 | NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 78 | if (!error && fetchResult && fetchResult.count) { 79 | SAConversation *existConversation = [fetchResult firstObject]; 80 | resultConversation = existConversation; 81 | } 82 | }]; 83 | return resultConversation; 84 | } 85 | 86 | - (NSArray *)currentConversationListWithUserID:(NSString *)userID limit:(NSUInteger)limit 87 | { 88 | NSSortDescriptor *otherUserIDSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"message.createdAt" ascending:NO]; 89 | NSArray *sortArray = [[NSArray alloc] initWithObjects: otherUserIDSortDescriptor, nil]; 90 | 91 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 92 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"localUser.userID = %@", userID]; 93 | fetchRequest.sortDescriptors = sortArray; 94 | fetchRequest.returnsObjectsAsFaults = NO; 95 | fetchRequest.fetchBatchSize = 6; 96 | fetchRequest.fetchLimit = limit; 97 | 98 | __block NSError *error; 99 | __block NSArray *resultArray = [[NSArray alloc] init]; 100 | [self.managedObjectContext performBlockAndWait:^{ 101 | NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 102 | if (!error && fetchResult && fetchResult.count) { 103 | resultArray = fetchResult; 104 | } 105 | }]; 106 | return resultArray; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Message.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Message.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | 11 | @class SAMessage; 12 | @class SAUser; 13 | 14 | @interface SADataManager (Message) 15 | 16 | - (void)insertOrUpdateMessagesWithObjects:(id)objects; 17 | - (SAMessage *)insertOrUpdateMessageWithObject:(id)object localUser:(SAUser *)localUser; 18 | - (NSArray *)currentMessageWithUserID:(NSString *)userID localUserID:(NSString *)localUserID limit:(NSUInteger)limit; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Photo.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Photo.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | 11 | @class SAPhoto; 12 | 13 | @interface SADataManager (Photo) 14 | 15 | - (SAPhoto *)insertOrUpdatePhotoWithObject:(id)object statusID:(NSString *)statusID; 16 | - (SAPhoto *)photoWithObject:(id)object; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Photo.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Photo.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager+Photo.h" 10 | #import "SAPhoto.h" 11 | 12 | @implementation SADataManager (Photo) 13 | 14 | static NSString *const ENTITY_NAME = @"SAPhoto"; 15 | 16 | - (SAPhoto *)insertOrUpdatePhotoWithObject:(id)object statusID:(NSString *)statusID 17 | { 18 | NSString *imageURL = [object objectForKey:@"imageurl"]; 19 | NSString *largeURL = [object objectForKey:@"largeurl"]; 20 | NSString *thumbURL = [object objectForKey:@"thumburl"]; 21 | NSString *photoURL = [object objectForKey:@"url"]; 22 | 23 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME]; 24 | fetchRequest.fetchLimit = 1; 25 | fetchRequest.predicate = [NSPredicate predicateWithFormat:@"statusID = %@", statusID]; 26 | 27 | __block NSError *error; 28 | __block SAPhoto *resultPhoto; 29 | [self.managedObjectContext performBlockAndWait:^{ 30 | NSArray *fetchResult = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 31 | if (!error && fetchResult && fetchResult.count) { 32 | resultPhoto = [fetchResult firstObject]; 33 | } else { 34 | SAPhoto *photo = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NAME inManagedObjectContext:self.managedObjectContext]; 35 | photo.statusID = statusID; 36 | photo.imageURL = imageURL; 37 | photo.largeURL = largeURL; 38 | photo.thumbURL = thumbURL; 39 | photo.photoURL = photoURL; 40 | resultPhoto = photo; 41 | } 42 | }]; 43 | return resultPhoto; 44 | } 45 | 46 | - (SAPhoto *)photoWithObject:(id)object 47 | { 48 | NSString *imageURL = [object objectForKey:@"imageurl"]; 49 | NSString *largeURL = [object objectForKey:@"largeurl"]; 50 | NSString *thumbURL = [object objectForKey:@"thumburl"]; 51 | NSString *photoURL = [object objectForKey:@"url"]; 52 | 53 | NSEntityDescription *entityDescription = [NSEntityDescription entityForName:ENTITY_NAME inManagedObjectContext:self.managedObjectContext]; 54 | SAPhoto *photo = [[SAPhoto alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil]; 55 | photo.imageURL = imageURL; 56 | photo.largeURL = largeURL; 57 | photo.thumbURL = thumbURL; 58 | photo.photoURL = photoURL; 59 | return photo; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+Status.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+Status.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/12/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | #import "SAStatus+CoreDataProperties.h" 11 | 12 | @class SAStatus; 13 | 14 | @interface SADataManager (Status) 15 | 16 | - (void)insertOrUpdateStatusWithObjects:(NSArray *)objects type:(SAStatusTypes)type; 17 | - (SAStatus *)insertOrUpdateStatusWithObject:(id)object localUser:(SAUser *)localUser type:(SAStatusTypes)type; 18 | - (void)currentTimeLineWithUserID:(NSString *)userID type:(SAStatusTypes)type offset:(NSUInteger)offset limit:(NSUInteger)limit completeHandler:(void(^)(NSArray *result))completeHandler; 19 | - (void)currentMentionTimeLineWithUserID:(NSString *)userID offset:(NSUInteger)offset limit:(NSUInteger)limit completeHandler:(void(^)(NSArray *result))completeHandler; 20 | - (void)currentPhotoTimeLineWithUserID:(NSString *)userID limit:(NSUInteger)limit completeHandler:(void(^)(NSArray *result))completeHandler; 21 | - (SAStatus *)statusWithObject:(id)object localUsers:(NSSet *)localUsers type:(SAStatusTypes)type; 22 | 23 | - (SAStatus *)statusWithID:(NSString *)statusID; 24 | - (void)deleteStatusWithID:(NSString *)statusID; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager+User.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager+User.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | 11 | @class SAUser; 12 | 13 | @interface SADataManager (User) 14 | 15 | - (SAUser *)currentUser; 16 | - (SAUser *)insertOrUpdateUserWithObject:(id)userObject local:(BOOL)local active:(BOOL)active token:(NSString *)token secret:(NSString *)secret; 17 | - (SAUser *)userWithID:(NSString *)userID; 18 | - (SAUser *)userWithObject:(id)object; 19 | 20 | - (BOOL)isLocalUserExist; 21 | - (void)setCurrentUserWithUserID:(NSString *)userID; 22 | - (void)deleteUserWithUserID:(NSString *)userID; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SADataManager : NSObject 13 | 14 | @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; 15 | 16 | + (SADataManager *)sharedManager; 17 | 18 | - (NSUInteger)sizeOfAllPersistentStore; 19 | - (void)saveContext; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /fansky/Services/SADataManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SADataManager.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/10/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SADataManager.h" 10 | #import "SAConstants.h" 11 | 12 | @interface SADataManager () 13 | 14 | @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; 15 | @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 16 | 17 | @end 18 | 19 | @implementation SADataManager 20 | 21 | + (SADataManager *)sharedManager 22 | { 23 | static SADataManager *sharedManager; 24 | static dispatch_once_t token = 0; 25 | dispatch_once(&token, ^{ 26 | if (!sharedManager) { 27 | sharedManager = [[SADataManager alloc] init]; 28 | } 29 | }); 30 | return sharedManager; 31 | } 32 | 33 | - (NSUInteger)sizeOfAllPersistentStore 34 | { 35 | NSArray *allStores = [self.persistentStoreCoordinator persistentStores]; 36 | NSUInteger totalBytes = 0; 37 | NSFileManager *fileManager = [NSFileManager defaultManager]; 38 | for (NSPersistentStore *store in allStores) { 39 | if (![store.URL isFileURL]) { 40 | continue; 41 | } 42 | totalBytes += [fileManager attributesOfItemAtPath:store.URL.path error:nil].fileSize; 43 | } 44 | return totalBytes; 45 | } 46 | 47 | #pragma mark - Core Data stack 48 | 49 | - (NSURL *)applicationDocumentsDirectory 50 | { 51 | return [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.fansky"]; 52 | } 53 | 54 | - (NSManagedObjectModel *)managedObjectModel 55 | { 56 | if (_managedObjectModel != nil) { 57 | return _managedObjectModel; 58 | } 59 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"fansky" withExtension:@"momd"]; 60 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 61 | return _managedObjectModel; 62 | } 63 | 64 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator 65 | { 66 | if (_persistentStoreCoordinator != nil) { 67 | return _persistentStoreCoordinator; 68 | } 69 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 70 | NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"fansky.sqlite"]; 71 | NSError *error = nil; 72 | NSString *failureReason = @"There was an error creating or loading the application's saved data."; 73 | NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @(YES), 74 | NSInferMappingModelAutomaticallyOption: @(YES)}; 75 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { 76 | NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 77 | dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; 78 | dict[NSLocalizedFailureReasonErrorKey] = failureReason; 79 | dict[NSUnderlyingErrorKey] = error; 80 | error = [NSError errorWithDomain:SA_APP_DOMAIN code:1000 userInfo:dict]; 81 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 82 | abort(); 83 | } 84 | return _persistentStoreCoordinator; 85 | } 86 | 87 | - (NSManagedObjectContext *)managedObjectContext 88 | { 89 | if (_managedObjectContext != nil) { 90 | return _managedObjectContext; 91 | } 92 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 93 | if (!coordinator) { 94 | return nil; 95 | } 96 | _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 97 | _managedObjectContext.persistentStoreCoordinator = coordinator; 98 | return _managedObjectContext; 99 | } 100 | 101 | #pragma mark - Core Data Saving support 102 | 103 | - (void)saveContext 104 | { 105 | NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 106 | if (managedObjectContext != nil) { 107 | NSError *error = nil; 108 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 109 | NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 110 | abort(); 111 | } 112 | } 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /fansky/Services/SANotificationManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SANotificationManager.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/30/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SANotificationManager : NSObject 12 | 13 | @property (nonatomic, readonly) NSUInteger timeLineCount; 14 | @property (nonatomic, readonly) NSUInteger mentionCount; 15 | @property (nonatomic, readonly) NSUInteger messageCount; 16 | @property (nonatomic, readonly) NSUInteger friendRequestCount; 17 | 18 | + (SANotificationManager *)sharedManager; 19 | 20 | - (void)startFetchNotificationCount; 21 | - (void)stopFetchNotificationCount; 22 | - (void)updateNotificationCount; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /fansky/Services/SANotificationManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SANotificationManager.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/30/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SANotificationManager.h" 10 | #import "SAAPIService.h" 11 | #import "SADataManager+Status.h" 12 | #import "SADataManager+User.h" 13 | #import "SAUser+CoreDataProperties.h" 14 | #import "SAStatus+CoreDataProperties.h" 15 | 16 | @interface SANotificationManager () 17 | 18 | @property (nonatomic, readwrite) NSUInteger timeLineCount; 19 | @property (nonatomic, readwrite) NSUInteger mentionCount; 20 | @property (nonatomic, readwrite) NSUInteger messageCount; 21 | @property (nonatomic, readwrite) NSUInteger friendRequestCount; 22 | @property (strong, nonatomic) NSTimer *fetchTimer; 23 | 24 | @end 25 | 26 | @implementation SANotificationManager 27 | 28 | static NSUInteger FETCH_TIME_INTERVAL = 30; 29 | 30 | + (SANotificationManager *)sharedManager 31 | { 32 | static SANotificationManager *sharedManager; 33 | static dispatch_once_t token = 0; 34 | dispatch_once(&token, ^{ 35 | if (!sharedManager) { 36 | sharedManager = [[SANotificationManager alloc] init]; 37 | } 38 | }); 39 | return sharedManager; 40 | } 41 | 42 | - (instancetype)init 43 | { 44 | self = [super init]; 45 | if (self) { 46 | _fetchTimer = [NSTimer timerWithTimeInterval:FETCH_TIME_INTERVAL target:self selector:@selector(updateNotificationCount) userInfo:nil repeats:YES]; 47 | } 48 | return self; 49 | } 50 | 51 | - (void)startFetchNotificationCount 52 | { 53 | [[NSRunLoop mainRunLoop] addTimer:self.fetchTimer forMode:NSDefaultRunLoopMode]; 54 | } 55 | 56 | - (void)stopFetchNotificationCount 57 | { 58 | [self.fetchTimer invalidate]; 59 | } 60 | 61 | - (void)updateNotificationCount 62 | { 63 | SAUser *currentUser = [SADataManager sharedManager].currentUser; 64 | if (currentUser) { 65 | [[SADataManager sharedManager] currentTimeLineWithUserID:currentUser.userID type:SAStatusTypeTimeLine offset:0 limit:1 completeHandler:^(NSArray *result) { 66 | if (result.count) { 67 | SAStatus *currentStatus = [result firstObject]; 68 | [[SAAPIService sharedSingleton] timeLineWithUserID:currentUser.userID sinceID:currentStatus.statusID maxID:nil count:60 success:^(id data) { 69 | NSArray *newTimeLine = (NSArray *)data; 70 | if (newTimeLine.count) { 71 | self.timeLineCount = newTimeLine.count; 72 | } 73 | } failure:nil]; 74 | } 75 | }]; 76 | 77 | [[SAAPIService sharedSingleton] accountNotificationWithSuccess:^(id data) { 78 | NSNumber *mentionCountValue = (NSNumber *)[data objectForKey:@"mentions"]; 79 | NSNumber *messageCountValue = (NSNumber *)[data objectForKey:@"direct_messages"]; 80 | NSNumber *friendRequestCountValue = (NSNumber *)[data objectForKey:@"friend_requests"]; 81 | self.mentionCount = mentionCountValue.integerValue; 82 | self.messageCount = messageCountValue.integerValue; 83 | self.friendRequestCount = friendRequestCountValue.integerValue; 84 | } failure:nil]; 85 | } 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /fansky/Utils/NSDate+Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Utils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (Utils) 12 | 13 | - (NSString *)friendlyDateString; 14 | - (NSString *)defaultDateString; 15 | - (NSString *)dateStringWithFormat:(NSString *)format; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Utils/NSDate+Utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Utils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/14/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "NSDate+Utils.h" 10 | 11 | @implementation NSDate (Utils) 12 | 13 | - (NSString *)friendlyDateString 14 | { 15 | NSDate *nowDate = [NSDate date]; 16 | NSTimeInterval timeInterval = [nowDate timeIntervalSinceDate:self]; 17 | 18 | NSInteger days = (NSInteger)(timeInterval / (3600 * 24)); 19 | NSInteger hours = (NSInteger)(timeInterval - days * 3600 * 24) / 3600; 20 | NSInteger minutes = (NSInteger)(timeInterval - days * 3600 * 24 - hours * 3600) / 60; 21 | 22 | if (days >= 1) { 23 | return [NSString stringWithFormat:@"%zd天前", days]; 24 | } else if (hours >= 1) { 25 | return [NSString stringWithFormat:@"%zd小时前", hours]; 26 | } else if (minutes >= 1) { 27 | return [NSString stringWithFormat:@"%zd分前", minutes]; 28 | } 29 | return [NSString stringWithFormat:@"刚才"]; 30 | } 31 | 32 | - (NSString *)defaultDateString 33 | { 34 | return [self dateStringWithFormat:@"yyyy-MM-dd HH:mm"]; 35 | } 36 | 37 | - (NSString *)dateStringWithFormat:(NSString *)format 38 | { 39 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 40 | dateFormatter.dateFormat = format; 41 | return [dateFormatter stringFromDate:self]; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /fansky/Utils/NSString+Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Utils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 8/24/15. 6 | // Copyright (c) 2015 Kaoputou. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Utils) 12 | 13 | - (NSDate *)dateWithDefaultFormat; 14 | - (NSDate *)dateWithFormat:(NSString *)format; 15 | 16 | - (NSString *)flattenHTML; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/Utils/NSString+Utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Utils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 8/24/15. 6 | // Copyright (c) 2015 Kaoputou. All rights reserved. 7 | // 8 | 9 | #import "NSString+Utils.h" 10 | 11 | @implementation NSString (Utils) 12 | 13 | - (NSDate *)dateWithDefaultFormat 14 | { 15 | return [self dateWithFormat:@"E MMM dd HH:mm:ss Z yyyy"]; 16 | } 17 | 18 | - (NSDate *)dateWithFormat:(NSString *)format 19 | { 20 | NSDateFormatter *dateFormatter =[[NSDateFormatter alloc] init]; 21 | dateFormatter.dateFormat = format; 22 | dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"GMT"]; 23 | NSDate *date =[dateFormatter dateFromString:self]; 24 | return date; 25 | } 26 | 27 | - (NSString *)flattenHTML 28 | { 29 | NSScanner *theScanner; 30 | NSString *text; 31 | NSString *result = [self copy]; 32 | theScanner = [NSScanner scannerWithString:self]; 33 | while ([theScanner isAtEnd] == NO) { 34 | [theScanner scanUpToString:@"<" intoString:NULL] ; 35 | [theScanner scanUpToString:@">" intoString:&text] ; 36 | result = [result stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%@>", text] withString:@""]; 37 | } 38 | return result; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /fansky/Utils/SAFileUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAFileUtils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 11/17/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAFileUtils : NSObject 12 | 13 | + (NSString *)sizeOfFolder:(NSString *)folderPath; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fansky/Utils/SAFileUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAFileUtils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 11/17/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAFileUtils.h" 10 | 11 | @implementation SAFileUtils 12 | 13 | + (NSString *)sizeOfFolder:(NSString *)folderPath 14 | { 15 | NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:folderPath error:nil]; 16 | NSEnumerator *contentsEnumurator = [contents objectEnumerator]; 17 | 18 | NSString *file; 19 | NSUInteger folderSize = 0; 20 | 21 | while (file = [contentsEnumurator nextObject]) { 22 | NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[folderPath stringByAppendingPathComponent:file] error:nil]; 23 | folderSize += [[fileAttributes objectForKey:NSFileSize] integerValue]; 24 | } 25 | 26 | NSString *folderSizeStr = [NSByteCountFormatter stringFromByteCount:folderSize countStyle:NSByteCountFormatterCountStyleFile]; 27 | return folderSizeStr; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /fansky/Utils/SAMessageDisplayUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessageDisplayUtils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/17/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SAMessageDisplayUtils : NSObject 12 | 13 | + (void)showInfoWithMessage:(NSString *)message; 14 | + (void)showProgressWithMessage:(NSString *)message; 15 | + (void)showShimmeringWithMessage:(NSString *)message; 16 | + (void)showSuccessWithMessage:(NSString *)message; 17 | + (void)showErrorWithMessage:(NSString *)message; 18 | + (void)dismiss; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /fansky/Utils/SAMessageDisplayUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessageDisplayUtils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/17/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAMessageDisplayUtils.h" 10 | #import 11 | 12 | @implementation SAMessageDisplayUtils 13 | 14 | + (void)showInfoWithMessage:(NSString *)message 15 | { 16 | dispatch_async(dispatch_get_main_queue(), ^{ 17 | [WSProgressHUD showImage:nil status:message]; 18 | }); 19 | } 20 | 21 | + (void)showProgressWithMessage:(NSString *)message 22 | { 23 | dispatch_async(dispatch_get_main_queue(), ^{ 24 | [WSProgressHUD showWithStatus:message]; 25 | }); 26 | } 27 | 28 | + (void)showShimmeringWithMessage:(NSString *)message 29 | { 30 | dispatch_async(dispatch_get_main_queue(), ^{ 31 | [WSProgressHUD showShimmeringString:message]; 32 | }); 33 | } 34 | 35 | + (void)showSuccessWithMessage:(NSString *)message 36 | { 37 | dispatch_async(dispatch_get_main_queue(), ^{ 38 | [WSProgressHUD showSuccessWithStatus:message]; 39 | }); 40 | } 41 | 42 | + (void)showErrorWithMessage:(NSString *)message 43 | { 44 | dispatch_async(dispatch_get_main_queue(), ^{ 45 | [WSProgressHUD showErrorWithStatus:message]; 46 | }); 47 | } 48 | 49 | + (void)dismiss 50 | { 51 | dispatch_async(dispatch_get_main_queue(), ^{ 52 | [WSProgressHUD dismiss]; 53 | }); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /fansky/Utils/UIColor+Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Utils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 11/1/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (Utils) 12 | 13 | + (UIColor *)fanskyBlue; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fansky/Utils/UIColor+Utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Utils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 11/1/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "UIColor+Utils.h" 10 | 11 | @implementation UIColor (Utils) 12 | 13 | + (UIColor *)fanskyBlue 14 | { 15 | static UIColor *color; 16 | static dispatch_once_t token = 0; 17 | dispatch_once(&token, ^{ 18 | if (!color) { 19 | color = [UIColor colorWithRed:85 / 255.0 green:172 / 255.0 blue:238 / 255.0 alpha:1]; 20 | } 21 | }); 22 | return color; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /fansky/Utils/UIImage+Utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Utils.h 3 | // fansky 4 | // 5 | // Created by Zzy on 11/2/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Utils) 12 | 13 | - (UIImage *)fixOrientation; 14 | - (UIImage *)circleImage:(CGFloat)width; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /fansky/Utils/UIImage+Utils.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Utils.m 3 | // fansky 4 | // 5 | // Created by Zzy on 11/2/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Utils.h" 10 | 11 | @implementation UIImage (Utils) 12 | 13 | - (UIImage *)fixOrientation 14 | { 15 | if (self.imageOrientation == UIImageOrientationUp) { 16 | return self; 17 | } 18 | 19 | CGAffineTransform transform = CGAffineTransformIdentity; 20 | switch (self.imageOrientation) { 21 | case UIImageOrientationDown: 22 | case UIImageOrientationDownMirrored: 23 | transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); 24 | transform = CGAffineTransformRotate(transform, M_PI); 25 | break; 26 | case UIImageOrientationLeft: 27 | case UIImageOrientationLeftMirrored: 28 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 29 | transform = CGAffineTransformRotate(transform, M_PI_2); 30 | break; 31 | case UIImageOrientationRight: 32 | case UIImageOrientationRightMirrored: 33 | transform = CGAffineTransformTranslate(transform, 0, self.size.height); 34 | transform = CGAffineTransformRotate(transform, -M_PI_2); 35 | break; 36 | default: 37 | break; 38 | } 39 | 40 | switch (self.imageOrientation) { 41 | case UIImageOrientationUpMirrored: 42 | case UIImageOrientationDownMirrored: 43 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 44 | transform = CGAffineTransformScale(transform, -1, 1); 45 | break; 46 | case UIImageOrientationLeftMirrored: 47 | case UIImageOrientationRightMirrored: 48 | transform = CGAffineTransformTranslate(transform, self.size.height, 0); 49 | transform = CGAffineTransformScale(transform, -1, 1); 50 | break; 51 | default: 52 | break; 53 | } 54 | 55 | CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage), CGImageGetBitmapInfo(self.CGImage)); 56 | CGContextConcatCTM(ctx, transform); 57 | switch (self.imageOrientation) { 58 | case UIImageOrientationLeft: 59 | case UIImageOrientationLeftMirrored: 60 | case UIImageOrientationRight: 61 | case UIImageOrientationRightMirrored: 62 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage); 63 | break; 64 | default: 65 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage); 66 | break; 67 | } 68 | 69 | CGImageRef cgImage = CGBitmapContextCreateImage(ctx); 70 | UIImage *newImage = [UIImage imageWithCGImage:cgImage]; 71 | CGContextRelease(ctx); 72 | CGImageRelease(cgImage); 73 | return newImage; 74 | } 75 | 76 | + (UIImage *)cropSquareImage:(UIImage *)image { 77 | CGImageRef sourceImageRef = [image CGImage];//将UIImage转换成CGImageRef 78 | CGFloat _imageWidth = image.size.width * image.scale; 79 | CGFloat _imageHeight = image.size.height * image.scale; 80 | CGFloat _width = _imageWidth > _imageHeight ? _imageHeight : _imageWidth; 81 | CGFloat _offsetX = (_imageWidth - _width) / 2; 82 | CGFloat _offsetY = (_imageHeight - _width) / 2; 83 | 84 | CGRect rect = CGRectMake(_offsetX, _offsetY, _width, _width); 85 | CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);//按照给定的矩形区域进行剪裁 86 | UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 87 | return newImage; 88 | } 89 | 90 | - (UIImage *)circleImage:(CGFloat)width { 91 | UIImage * squareImage= [UIImage cropSquareImage:self]; 92 | CGRect rect = CGRectMake(0, 0, width, width); 93 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0); 94 | CGContextRef context = UIGraphicsGetCurrentContext(); 95 | CGContextSetLineWidth(context, 2); 96 | CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); 97 | CGContextAddEllipseInRect(context, rect); 98 | CGContextClip(context); 99 | 100 | [squareImage drawInRect:rect]; 101 | CGContextAddEllipseInRect(context, rect); 102 | CGContextStrokePath(context); 103 | UIImage *newimg = UIGraphicsGetImageFromCurrentImageContext(); 104 | UIGraphicsEndImageContext(); 105 | return newimg; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /fansky/Views/SAConversationCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversationCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAUser; 12 | @class SAConversation; 13 | @class SAConversationCell; 14 | 15 | @protocol SAConversationCellDelegate 16 | 17 | - (void)conversationCell:(SAConversationCell *)conversationCell avatarImageViewTouchUp:(id)sender; 18 | 19 | @end 20 | 21 | @interface SAConversationCell : UITableViewCell 22 | 23 | @property (weak, nonatomic) id delegate; 24 | @property (strong, nonatomic) SAUser *otherUser; 25 | 26 | - (void)configWithMessage:(SAConversation *)conversation; 27 | - (void)loadImage; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /fansky/Views/SAConversationCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAConversationCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAConversationCell.h" 10 | #import "SADataManager+User.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import "SAConversation+CoreDataProperties.h" 13 | #import "SAMessage+CoreDataProperties.h" 14 | #import "NSDate+Utils.h" 15 | #import 16 | 17 | @interface SAConversationCell () 18 | 19 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 20 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 21 | @property (weak, nonatomic) IBOutlet UILabel *userIDLabel; 22 | @property (weak, nonatomic) IBOutlet UILabel *timeLabel; 23 | 24 | @property (strong, nonatomic) SAConversation *conversation; 25 | 26 | @end 27 | 28 | @implementation SAConversationCell 29 | 30 | - (void)prepareForReuse 31 | { 32 | [super prepareForReuse]; 33 | 34 | self.nameLabel.text = nil; 35 | self.userIDLabel.text = nil; 36 | [self.avatarImageView setImage:nil]; 37 | } 38 | 39 | - (void)configWithMessage:(SAConversation *)conversation 40 | { 41 | self.conversation = conversation; 42 | if ([self.conversation.otherUserID isEqualToString:self.conversation.message.senderID]) { 43 | self.otherUser = self.conversation.message.sender; 44 | } else { 45 | self.otherUser = self.conversation.message.recipient; 46 | } 47 | [self updateInterface]; 48 | } 49 | 50 | - (void)updateInterface 51 | { 52 | self.avatarImageView.layer.rasterizationScale = [UIScreen mainScreen].scale; 53 | 54 | self.nameLabel.text = self.otherUser.name; 55 | self.userIDLabel.text = [NSString stringWithFormat:@"@%@", self.otherUser.userID]; 56 | self.timeLabel.text = [self.conversation.message.createdAt friendlyDateString]; 57 | } 58 | 59 | - (void)loadImage 60 | { 61 | [self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:self.otherUser.profileImageURL] placeholderImage:[UIImage imageNamed:@"BackgroundAvatar"] options:SDWebImageRefreshCached]; 62 | } 63 | 64 | #pragma mark - EventHandler 65 | 66 | - (IBAction)avatarImageTouchUp:(id)sender 67 | { 68 | if (self.delegate && [self.delegate respondsToSelector:@selector(conversationCell:avatarImageViewTouchUp:)]) { 69 | [self.delegate conversationCell:self avatarImageViewTouchUp:sender]; 70 | } 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /fansky/Views/SAFriendCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAFriendCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/25/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, SAFriendCellType) 12 | { 13 | SAFriendCellTypeFollow, 14 | SAFriendCellTypeFriend, 15 | SAFriendCellTypeFriendPopup, 16 | SAFriendCellTypeRequest 17 | }; 18 | 19 | @class SAFriend; 20 | 21 | @interface SAFriendCell : UITableViewCell 22 | 23 | - (void)configWithFriend:(SAFriend *)friend type:(SAFriendCellType)type; 24 | - (void)loadImage; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /fansky/Views/SAFriendCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAFriendCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/25/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAFriendCell.h" 10 | #import "SAFriend.h" 11 | #import "SAAPIService.h" 12 | #import "SAMessageDisplayUtils.h" 13 | #import "UIColor+Utils.h" 14 | #import 15 | 16 | @interface SAFriendCell () 17 | 18 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 19 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 20 | @property (weak, nonatomic) IBOutlet UILabel *friendIDLabel; 21 | @property (weak, nonatomic) IBOutlet UIButton *followButton; 22 | 23 | @property (strong, nonatomic) SAFriend *friend; 24 | @property (nonatomic) SAFriendCellType type; 25 | 26 | @end 27 | 28 | @implementation SAFriendCell 29 | 30 | - (void)awakeFromNib 31 | { 32 | [super awakeFromNib]; 33 | self.followButton.layer.borderColor = [UIColor fanskyBlue].CGColor; 34 | } 35 | 36 | - (void)prepareForReuse 37 | { 38 | self.nameLabel.text = nil; 39 | self.friendIDLabel.text = nil; 40 | [self.avatarImageView setImage:nil]; 41 | } 42 | 43 | - (void)configWithFriend:(SAFriend *)friend type:(SAFriendCellType)type 44 | { 45 | self.friend = friend; 46 | self.type = type; 47 | [self updateInterface]; 48 | } 49 | 50 | - (void)updateInterface 51 | { 52 | self.avatarImageView.layer.rasterizationScale = [UIScreen mainScreen].scale; 53 | 54 | [self.followButton.layer setRasterizationScale:[UIScreen mainScreen].scale]; 55 | self.nameLabel.text = self.friend.name; 56 | self.friendIDLabel.text = [NSString stringWithFormat:@"@%@", self.friend.friendID]; 57 | if (self.type != SAFriendCellTypeRequest && self.type != SAFriendCellTypeFriendPopup) { 58 | self.followButton.hidden = NO; 59 | if ([self.friend.following isEqualToNumber:@(YES)]) { 60 | self.followButton.titleLabel.text = @"取消关注"; 61 | [self.followButton setTitle:@"取消关注" forState:UIControlStateNormal]; 62 | } else { 63 | self.followButton.titleLabel.text = @"+关注"; 64 | [self.followButton setTitle:@"+关注" forState:UIControlStateNormal]; 65 | } 66 | } else { 67 | self.followButton.hidden = YES; 68 | } 69 | } 70 | 71 | - (void)loadImage 72 | { 73 | [self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:self.friend.profileImageURL] placeholderImage:[UIImage imageNamed:@"BackgroundAvatar"] options:SDWebImageRefreshCached]; 74 | } 75 | 76 | #pragma mark - EventHandler 77 | 78 | - (IBAction)followButtonTouchUp:(id)sender 79 | { 80 | if ([self.friend.following isEqualToNumber:@(NO)]) { 81 | [[SAAPIService sharedSingleton] followUserWithID:self.friend.friendID success:^(id data) { 82 | self.friend.following = @(YES); 83 | [SAMessageDisplayUtils showSuccessWithMessage:@"关注成功"]; 84 | [self updateInterface]; 85 | } failure:^(NSString *error) { 86 | [SAMessageDisplayUtils showInfoWithMessage:error]; 87 | }]; 88 | } else { 89 | [[SAAPIService sharedSingleton] unfollowUserWithID:self.friend.friendID success:^(id data) { 90 | self.friend.following = @(NO); 91 | [SAMessageDisplayUtils showSuccessWithMessage:@"取消关注成功"]; 92 | [self updateInterface]; 93 | } failure:^(NSString *error) { 94 | [SAMessageDisplayUtils showErrorWithMessage:error]; 95 | }]; 96 | } 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /fansky/Views/SAMessageCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessageCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAMessage; 12 | 13 | @interface SAMessageCell : UITableViewCell 14 | 15 | - (void)configWithMessage:(SAMessage *)message; 16 | - (void)loadImage; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /fansky/Views/SAMessageCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAMessageCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/20/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAMessageCell.h" 10 | #import "SAMessage+CoreDataProperties.h" 11 | #import "SAUser+CoreDataProperties.h" 12 | #import 13 | 14 | @interface SAMessageCell () 15 | 16 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 17 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 18 | @property (weak, nonatomic) IBOutlet UILabel *userIDLabel; 19 | 20 | @property (strong, nonatomic) SAMessage *message; 21 | 22 | @end 23 | 24 | @implementation SAMessageCell 25 | 26 | - (void)configWithMessage:(SAMessage *)message 27 | { 28 | self.message = message; 29 | [self updateInterface]; 30 | } 31 | 32 | - (void)updateInterface 33 | { 34 | self.nameLabel.text = self.message.sender.name; 35 | self.userIDLabel.text = self.message.sender.userID; 36 | } 37 | 38 | - (void)loadImage 39 | { 40 | [self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:self.message.sender.profileImageURL] placeholderImage:[UIImage imageNamed:@"BackgroundAvatar"] options:SDWebImageRefreshCached]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /fansky/Views/SAPhotoTimeLineCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhotoTimeLineCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAStatus; 12 | @class SAPhotoTimeLineCell; 13 | 14 | @protocol SAPhotoTimeLineCellDelegate 15 | 16 | - (void)photoTimeLineCell:(SAPhotoTimeLineCell *)photoTimeLineCell imageViewTouchUp:(id)sender; 17 | 18 | @end 19 | 20 | @interface SAPhotoTimeLineCell : UICollectionViewCell 21 | 22 | @property (weak, nonatomic) SAStatus *status; 23 | @property (weak, nonatomic) id delegate; 24 | 25 | - (void)configWithStatus:(SAStatus *)status; 26 | - (void)loadImage; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /fansky/Views/SAPhotoTimeLineCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAPhotoTimeLineCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAPhotoTimeLineCell.h" 10 | #import "SAStatus+CoreDataProperties.h" 11 | #import "SAPhoto.h" 12 | #import 13 | 14 | @interface SAPhotoTimeLineCell () 15 | 16 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 17 | @property (weak, nonatomic) IBOutlet UIImageView *iconGIFImageView; 18 | 19 | @end 20 | 21 | @implementation SAPhotoTimeLineCell 22 | 23 | - (void)prepareForReuse 24 | { 25 | [super prepareForReuse]; 26 | 27 | [self.imageView setImage:nil]; 28 | self.iconGIFImageView.hidden = YES; 29 | } 30 | 31 | - (void)configWithStatus:(SAStatus *)status 32 | { 33 | self.status = status; 34 | 35 | [self updateInterface]; 36 | } 37 | 38 | - (void)updateInterface 39 | { 40 | self.imageView.layer.rasterizationScale = [UIScreen mainScreen].scale; 41 | } 42 | 43 | - (void)loadImage 44 | { 45 | [self.imageView sd_setImageWithURL:[NSURL URLWithString:self.status.photo.largeURL] placeholderImage:[UIImage imageNamed:@"BackgroundImage"] options:SDWebImageRefreshCached completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 46 | if ([self.status.photo.largeURL hasSuffix:@".gif"]) { 47 | self.iconGIFImageView.hidden = NO; 48 | self.imageView.image = image.images.firstObject; 49 | } 50 | }]; 51 | } 52 | 53 | - (IBAction)imageViewTouchUp:(id)sender 54 | { 55 | if (self.delegate && [self.delegate respondsToSelector:@selector(photoTimeLineCell:imageViewTouchUp:)]) { 56 | [self.delegate photoTimeLineCell:self imageViewTouchUp:sender]; 57 | } 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /fansky/Views/SATimeLineCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SATimeLineCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/18/15. 6 | // Copyright © 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAStatus; 12 | @class SATimeLineCell; 13 | 14 | @protocol SATimeLineCellDelegate 15 | 16 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell avatarImageViewTouchUp:(id)sender; 17 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell contentImageViewTouchUp:(id)sender; 18 | - (void)timeLineCell:(SATimeLineCell *)timeLineCell contentURLTouchUp:(id)sender; 19 | 20 | @end 21 | 22 | @interface SATimeLineCell : UITableViewCell 23 | 24 | @property (weak, nonatomic) IBOutlet UIImageView *contentImageView; 25 | 26 | @property (weak, nonatomic) id delegate; 27 | @property (weak, nonatomic) SAStatus *status; 28 | @property (strong, nonatomic) NSURL *selectedURL; 29 | 30 | - (void)configWithStatus:(SAStatus *)status; 31 | - (void)loadAllImages; 32 | - (CGRect)sourceRectWithLocation:(CGPoint)location; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /fansky/Views/SATrendCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SATrendCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/16. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, SATrendCellType) { 12 | SATrendCellTypeHot = 1, 13 | SATrendCellTypeRandom = 2 14 | }; 15 | 16 | @class SATrend; 17 | 18 | @interface SATrendCell : UITableViewCell 19 | 20 | - (void)configWithTrend:(SATrend *)trend type:(SATrendCellType)type; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /fansky/Views/SATrendCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SATrendCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 16/4/16. 6 | // Copyright © 2016年 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SATrendCell.h" 10 | #import "SATrend.h" 11 | 12 | @interface SATrendCell () 13 | 14 | @property (weak, nonatomic) IBOutlet UILabel *titleLabel; 15 | @property (weak, nonatomic) IBOutlet UILabel *detailLabel; 16 | 17 | @end 18 | 19 | @implementation SATrendCell 20 | 21 | - (void)awakeFromNib 22 | { 23 | [super awakeFromNib]; 24 | } 25 | 26 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 27 | { 28 | [super setSelected:selected animated:animated]; 29 | } 30 | 31 | - (void)configWithTrend:(SATrend *)trend type:(SATrendCellType)type 32 | { 33 | if (type == SATrendCellTypeHot && trend) { 34 | self.titleLabel.text = trend.name; 35 | self.detailLabel.text = trend.query; 36 | } else if (type == SATrendCellTypeRandom) { 37 | self.titleLabel.text = @"随便看看"; 38 | self.detailLabel.text = @""; 39 | } 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /fansky/Views/SATrendCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /fansky/Views/SAUserCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserCell.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/11/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAUser; 12 | 13 | @interface SAUserCell : UITableViewCell 14 | 15 | - (void)configWithUser:(SAUser *)user; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fansky/Views/SAUserCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserCell.m 3 | // fansky 4 | // 5 | // Created by Zzy on 9/11/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import "SAUserCell.h" 10 | #import "SAUser+CoreDataProperties.h" 11 | #import 12 | 13 | @interface SAUserCell () 14 | 15 | @property (weak, nonatomic) IBOutlet UIImageView *avatarImageView; 16 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 17 | @property (weak, nonatomic) IBOutlet UILabel *IDLabel; 18 | 19 | @end 20 | 21 | @implementation SAUserCell 22 | 23 | - (void)configWithUser:(SAUser *)user 24 | { 25 | [self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:user.profileImageURL] placeholderImage:nil options:SDWebImageRefreshCached]; 26 | self.nameLabel.text = user.name; 27 | self.IDLabel.text = [NSString stringWithFormat:@"@%@", user.userID]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /fansky/Views/SAUserHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAUserHeaderView.h 3 | // fansky 4 | // 5 | // Created by Zzy on 9/15/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SAUserHeaderView; 12 | 13 | @protocol SAUserHeaderViewDelegate 14 | 15 | - (void)userHeaderView:(SAUserHeaderView *)userHeaderView settingButtonTouchUp:(id)sender; 16 | - (void)userHeaderView:(SAUserHeaderView *)userHeaderView friendsCountButtonTouchUp:(id)sender; 17 | - (void)userHeaderView:(SAUserHeaderView *)userHeaderView followersCountButtonTouchUp:(id)sender; 18 | - (void)userHeaderView:(SAUserHeaderView *)userHeaderView userInfoButtonTouchUp:(id)sender; 19 | - (void)userHeaderView:(SAUserHeaderView *)userHeaderView modifyInfoButtonTouchUp:(id)sender; 20 | 21 | @end 22 | 23 | @interface SAUserHeaderView : UIView 24 | 25 | @property (weak, nonatomic) id delegate; 26 | 27 | - (void)configWithUserID:(NSString *)userID; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /fansky/fansky.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.fansky 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /fansky/fansky.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | fansky 7.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /fansky/fansky.xcdatamodeld/fansky.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /fansky/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // fansky 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SAAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SAAppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /fansky/zh-Hans.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /fanskyTests/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 | -------------------------------------------------------------------------------- /fanskyTests/fanskyTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // fanskyTests.m 3 | // fanskyTests 4 | // 5 | // Created by Zzy on 6/17/15. 6 | // Copyright (c) 2015 Zzy. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface fanskyTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation fanskyTests 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 | --------------------------------------------------------------------------------