├── .gitignore ├── .gitmodules ├── JLSinaWeibo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── JLSinaWeibo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── JLSinaWeibo.xcscmblueprint ├── LICENSE ├── Podfile ├── Podfile.lock ├── README.md ├── SinaMBlog ├── AppDelegate.h ├── AppDelegate.m ├── Category │ ├── NSString+StringValue.h │ ├── NSString+StringValue.m │ ├── UIImage+nimbusImageNamed.h │ ├── UIImage+nimbusImageNamed.m │ ├── UIView+findViewController.h │ └── UIView+findViewController.m ├── Common │ ├── SMAPIClient.h │ ├── SMAPIClient.m │ └── SMJSONKeys.h ├── Controllers │ ├── LocationManager │ │ ├── SMLocationViewController.h │ │ └── SMLocationViewController.mm │ ├── SMCommentOrRetweetC.h │ ├── SMCommentOrRetweetC.m │ ├── SMEmotionC.h │ ├── SMEmotionC.m │ ├── SMFriendsC.h │ ├── SMFriendsC.m │ ├── SMHomeTimlineListC.h │ ├── SMHomeTimlineListC.m │ ├── SMLoginC.h │ ├── SMLoginC.m │ ├── SMMBlogPostC.h │ ├── SMMBlogPostC.m │ ├── SMPageTimlineListC.h │ ├── SMPageTimlineListC.m │ ├── SMPhotoBrowseC.h │ ├── SMPhotoBrowseC.m │ ├── SMPostPhotoBrowseC.h │ ├── SMPostPhotoBrowseC.m │ ├── SMTrendsC.h │ └── SMTrendsC.m ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── Entities │ ├── SMEmotionEntity.h │ ├── SMEmotionEntity.m │ ├── SMFriendEntity.h │ ├── SMFriendEntity.m │ ├── SMFriendListEntity.h │ ├── SMFriendListEntity.m │ ├── SMSectionItemBaseEntity.h │ ├── SMSectionItemBaseEntity.m │ ├── SMSectionListBaseEntity.h │ ├── SMSectionListBaseEntity.m │ ├── SMStatusEntity.h │ ├── SMStatusEntity.m │ ├── SMTrendEntity.h │ ├── SMTrendEntity.m │ ├── SMTrendListEntity.h │ ├── SMTrendListEntity.m │ ├── SMUserInfoEntity.h │ └── SMUserInfoEntity.m ├── Images │ ├── Screenshot │ │ ├── homepage.png │ │ ├── postnewstatus.png │ │ └── repost.png │ └── Sina │ │ ├── 37x-Checkmark.png │ │ ├── 37x-Checkmark@2x.png │ │ ├── ReadMe │ │ ├── clearbutton_background.png │ │ ├── clearbutton_background@2x.png │ │ ├── compose_camerabutton_background.png │ │ ├── compose_camerabutton_background@2x.png │ │ ├── compose_camerabutton_background_highlighted.png │ │ ├── compose_camerabutton_background_highlighted@2x.png │ │ ├── compose_checkbox.png │ │ ├── compose_checkbox@2x.png │ │ ├── compose_checkbox_checked.png │ │ ├── compose_checkbox_checked@2x.png │ │ ├── compose_emoticonbutton_background.png │ │ ├── compose_emoticonbutton_background@2x.png │ │ ├── compose_emoticonbutton_background_highlighted.png │ │ ├── compose_emoticonbutton_background_highlighted@2x.png │ │ ├── compose_keyboardbutton_background.png │ │ ├── compose_keyboardbutton_background@2x.png │ │ ├── compose_keyboardbutton_background_highlighted.png │ │ ├── compose_keyboardbutton_background_highlighted@2x.png │ │ ├── compose_locatebutton_background.png │ │ ├── compose_locatebutton_background@2x.png │ │ ├── compose_locatebutton_background_highlighted.png │ │ ├── compose_locatebutton_background_highlighted@2x.png │ │ ├── compose_mentionbutton_background.png │ │ ├── compose_mentionbutton_background@2x.png │ │ ├── compose_mentionbutton_background_highlighted.png │ │ ├── compose_mentionbutton_background_highlighted@2x.png │ │ ├── compose_placebutton_background.png │ │ ├── compose_placebutton_background@2x.png │ │ ├── compose_trendbutton_background.png │ │ ├── compose_trendbutton_background@2x.png │ │ ├── compose_trendbutton_background_highlighted.png │ │ ├── compose_trendbutton_background_highlighted@2x.png │ │ ├── emoticon_keyboard_background.png │ │ ├── emoticon_keyboard_background@2x.png │ │ ├── icon_default │ │ ├── Default-568h@2x.png │ │ ├── Default.png │ │ ├── Default@2x.png │ │ ├── icon.png │ │ ├── icon@2x.png │ │ ├── icon_os7.png │ │ └── icon_os7@2x.png │ │ ├── navigationbar_button_delete_background.png │ │ ├── navigationbar_button_delete_background@2x.png │ │ ├── preview_button.png │ │ ├── preview_button@2x.png │ │ ├── preview_save_icon.png │ │ └── preview_save_icon@2x.png ├── JLSinaWeibo-Info.plist ├── JLSinaWeibo-Prefix.pch ├── Models │ ├── SMAuthorizeModel.h │ ├── SMAuthorizeModel.m │ ├── SMFriendsModel.h │ ├── SMFriendsModel.m │ ├── SMMBlogPostModel.h │ ├── SMMBlogPostModel.m │ ├── SMMaxIdTimelineModel.h │ ├── SMMaxIdTimelineModel.m │ ├── SMMaxIdTimelineTypeModel.h │ ├── SMMaxIdTimelineTypeModel.m │ ├── SMPageTimelineModel.h │ ├── SMPageTimelineModel.m │ ├── SMTrendsModel.h │ ├── SMTrendsModel.m │ ├── SMUserInfoModel.h │ └── SMUserInfoModel.m ├── SMGlobalConfig.h ├── SMGlobalConfig.m ├── Util │ ├── SMNetworkSpy.h │ ├── SMNetworkSpy.m │ ├── SMRegularParser.h │ └── SMRegularParser.m ├── Views │ ├── SMFriendCell.h │ ├── SMFriendCell.m │ ├── SMFullScreenPhotoBrowseView.h │ ├── SMFullScreenPhotoBrowseView.m │ ├── SMPostButtonBar.h │ ├── SMPostButtonBar.m │ ├── SMStatusCell.h │ ├── SMStatusCell.m │ ├── SMTrendCell.h │ ├── SMTrendCell.m │ ├── TTButtonBar.h │ └── TTButtonBar.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── TODO └── vendor ├── NYXImagesKit ├── Categories │ ├── UIImage+Blurring.h │ ├── UIImage+Blurring.m │ ├── UIImage+Enhancing.h │ ├── UIImage+Enhancing.m │ ├── UIImage+Filtering.h │ ├── UIImage+Filtering.m │ ├── UIImage+Masking.h │ ├── UIImage+Masking.m │ ├── UIImage+Reflection.h │ ├── UIImage+Reflection.m │ ├── UIImage+Resizing.h │ ├── UIImage+Resizing.m │ ├── UIImage+Rotating.h │ ├── UIImage+Rotating.m │ ├── UIImage+Saving.h │ ├── UIImage+Saving.m │ ├── UIImage+fixOrientation.h │ └── UIImage+fixOrientation.m └── Helper │ ├── NYXImagesHelper.h │ ├── NYXImagesHelper.m │ └── NYXImagesKit.h ├── Pinyin ├── pinyin.c └── pinyin.h ├── Reachability ├── Reachability.h └── Reachability.m ├── UIScrollView+ZoomToPoint ├── UIScrollView+ZoomToPoint.h └── UIScrollView+ZoomToPoint.m └── libWeiboSDK ├── WeiboSDK.bundle └── images │ ├── close.png │ ├── close@2x.png │ ├── compose_keyboardbutton_background.png │ ├── compose_keyboardbutton_background@2x.png │ ├── compose_toolbar_background.png │ ├── compose_toolbar_background@2x.png │ ├── navigationbar_background.png │ ├── navigationbar_background@2x.png │ ├── navigationbar_background_os7.png │ └── navigationbar_background_os7@2x.png ├── WeiboSDK.h └── libWeiboSDK.a /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 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 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/JLNimbusTimeline"] 2 | path = vendor/JLNimbusTimeline 3 | url = https://github.com/jimneylee/JLNimbusTimeline.git 4 | [submodule "vendor/320Categories"] 5 | path = vendor/320Categories 6 | url = https://github.com/jimneylee/320Categories.git 7 | -------------------------------------------------------------------------------- /JLSinaWeibo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JLSinaWeibo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /JLSinaWeibo.xcworkspace/xcshareddata/JLSinaWeibo.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "3992E89CEFF415BA2A361931C8A47674B6DC8846", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "3992E89CEFF415BA2A361931C8A47674B6DC8846" : 0, 8 | "3696B39AF9A7D45AA2A36BD621E04A71FEC24306" : 0, 9 | "E252D7BD2F0F58EA499CABA45B3A8E07286F0E94" : 0 10 | }, 11 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "44E6A8A1-2C06-4C4C-B071-F680CDE3A666", 12 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 13 | "3992E89CEFF415BA2A361931C8A47674B6DC8846" : "JLSinaMBlogNimbus\/", 14 | "3696B39AF9A7D45AA2A36BD621E04A71FEC24306" : "JLSinaMBlogNimbus\/vendor\/JLNimbusTimeline\/", 15 | "E252D7BD2F0F58EA499CABA45B3A8E07286F0E94" : "JLSinaMBlogNimbus\/vendor\/320Categories\/" 16 | }, 17 | "DVTSourceControlWorkspaceBlueprintNameKey" : "JLSinaWeibo", 18 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 19 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "JLSinaWeibo.xcworkspace", 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 21 | { 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/jimneylee\/JLNimbusTimeline.git", 23 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 24 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3696B39AF9A7D45AA2A36BD621E04A71FEC24306" 25 | }, 26 | { 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/jimneylee\/JLSinaMBlogNimbus.git", 28 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 29 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "3992E89CEFF415BA2A361931C8A47674B6DC8846" 30 | }, 31 | { 32 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/jimneylee\/320Categories.git", 33 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 34 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "E252D7BD2F0F58EA499CABA45B3A8E07286F0E94" 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 jimneylee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios,'7.0' 2 | 3 | pod 'Nimbus', '~> 1.3.0' 4 | pod 'MBProgressHUD', '~> 0.9.2' 5 | pod 'MTStatusBarOverlay', '~> 0.9.1' 6 | pod 'SDWebImage', '~> 3.7.5' -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (2.6.3): 3 | - AFNetworking/NSURLConnection (= 2.6.3) 4 | - AFNetworking/NSURLSession (= 2.6.3) 5 | - AFNetworking/Reachability (= 2.6.3) 6 | - AFNetworking/Security (= 2.6.3) 7 | - AFNetworking/Serialization (= 2.6.3) 8 | - AFNetworking/UIKit (= 2.6.3) 9 | - AFNetworking/NSURLConnection (2.6.3): 10 | - AFNetworking/Reachability 11 | - AFNetworking/Security 12 | - AFNetworking/Serialization 13 | - AFNetworking/NSURLSession (2.6.3): 14 | - AFNetworking/Reachability 15 | - AFNetworking/Security 16 | - AFNetworking/Serialization 17 | - AFNetworking/Reachability (2.6.3) 18 | - AFNetworking/Security (2.6.3) 19 | - AFNetworking/Serialization (2.6.3) 20 | - AFNetworking/UIKit (2.6.3): 21 | - AFNetworking/NSURLConnection 22 | - AFNetworking/NSURLSession 23 | - MBProgressHUD (0.9.2) 24 | - MTStatusBarOverlay (0.9.1) 25 | - Nimbus (1.3.0): 26 | - Nimbus/AttributedLabel (= 1.3.0) 27 | - Nimbus/Badge (= 1.3.0) 28 | - Nimbus/Collections (= 1.3.0) 29 | - Nimbus/Core (= 1.3.0) 30 | - Nimbus/CSS (= 1.3.0) 31 | - Nimbus/Interapp (= 1.3.0) 32 | - Nimbus/Launcher (= 1.3.0) 33 | - Nimbus/Models (= 1.3.0) 34 | - Nimbus/NetworkControllers (= 1.3.0) 35 | - Nimbus/NetworkImage (= 1.3.0) 36 | - Nimbus/Overview (= 1.3.0) 37 | - Nimbus/PagingScrollView (= 1.3.0) 38 | - Nimbus/Photos (= 1.3.0) 39 | - Nimbus/Textfield (= 1.3.0) 40 | - Nimbus/WebController (= 1.3.0) 41 | - Nimbus/AttributedLabel (1.3.0): 42 | - Nimbus/Core 43 | - Nimbus/Badge (1.3.0): 44 | - Nimbus/Core 45 | - Nimbus/Collections (1.3.0): 46 | - Nimbus/Core 47 | - Nimbus/Core (1.3.0) 48 | - Nimbus/CSS (1.3.0): 49 | - AFNetworking (~> 2.6) 50 | - Nimbus/Core 51 | - Nimbus/Textfield 52 | - Nimbus/Interapp (1.3.0): 53 | - Nimbus/Core 54 | - Nimbus/Launcher (1.3.0): 55 | - Nimbus/Core 56 | - Nimbus/PagingScrollView 57 | - Nimbus/Models (1.3.0): 58 | - Nimbus/Core 59 | - Nimbus/NetworkControllers (1.3.0): 60 | - Nimbus/Core 61 | - Nimbus/NetworkImage (1.3.0): 62 | - AFNetworking (~> 2.6) 63 | - Nimbus/Core 64 | - Nimbus/Overview (1.3.0): 65 | - Nimbus/Core 66 | - Nimbus/Models 67 | - Nimbus/PagingScrollView (1.3.0): 68 | - Nimbus/Core 69 | - Nimbus/Photos (1.3.0): 70 | - Nimbus/Core 71 | - Nimbus/PagingScrollView 72 | - Nimbus/Textfield (1.3.0): 73 | - Nimbus/Core 74 | - Nimbus/WebController (1.3.0): 75 | - Nimbus/Core 76 | - SDWebImage (3.7.5): 77 | - SDWebImage/Core (= 3.7.5) 78 | - SDWebImage/Core (3.7.5) 79 | 80 | DEPENDENCIES: 81 | - MBProgressHUD (~> 0.9.2) 82 | - MTStatusBarOverlay (~> 0.9.1) 83 | - Nimbus (~> 1.3.0) 84 | - SDWebImage (~> 3.7.5) 85 | 86 | SPEC CHECKSUMS: 87 | AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 88 | MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1 89 | MTStatusBarOverlay: 258a1ee369f4dc4b94107d02cfd7f6b1317c421b 90 | Nimbus: e7f33bc6d6cb4fe5ea0aee0c7e0883696123422c 91 | SDWebImage: 69c6303e3348fba97e03f65d65d4fbc26740f461 92 | 93 | COCOAPODS: 0.39.0 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Screenshots 2 | ![image](http://cc.cocimg.com/bbs/attachment/Fid_19/19_22435_9c77b66707adb15.gif) 3 | ![image](http://git.oschina.net/jimneylee/SinaMBlogNimbus/raw/master/SinaMBlog/Images/Screenshot/postnewstatus.png) 4 | ![image](http://git.oschina.net/jimneylee/SinaMBlogNimbus/raw/master/SinaMBlog/Images/Screenshot/repost.png) 5 | 6 | # SinaMBlogNimbus 7 | 基于轻量级iOS开发框架[Nimbus](https://github.com/jverkoey/nimbus),网络层采用AFNetworking, 8 | 9 | 在此基础上进行二次构建,可以简单、便捷地处理和显示列表数据, 10 | 11 | 通过制作iOS7上新浪微博APP的首页,介绍框架的使用,通过开源分享,一起交流进步。 12 | 13 | 主要分享的技术点如下: 14 | 15 | * 1、二次构建,简化tableView网络数据请求和显示 16 | 17 | * 2、类似官方APP图文的布局和关键字的识别和交互 18 | 19 | * 3、微博列表查看原图功能实现 20 | 21 | * 4、发布微博、拍照及获取地理位置 22 | 23 | PS:以前项目中主要使用[three20](https://github.com/facebook/three20)开发APP,了解过three20的同学,应该比较熟悉nimbus的作者,不熟悉请google之。 24 | 25 | # 更新依赖库 26 | 1、更新submodule 27 | ``` bash 28 | $ git submodule init 29 | $ git submodule update 30 | ``` 31 | 32 | 2、使用[CocoaPods](http://cocoapods.org)的命令安装其他依赖库 33 | ``` bash 34 | $ pod update 35 | ``` 36 | 注:如需要添加其他依赖库,请修改Podfile 37 | 38 | # ERROR解决方法 39 | 40 | 1、若出现这个问题:diff: /../Podfile.lock: No such file or directory 41 | diff: /Manifest.lock: No such file or directory 42 | error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation. 43 | ``` bash 44 | $ pod update 45 | ``` 46 | 47 | # DONE 48 | * 1、支持XCode4 & XCode5 & iOS7 49 | 50 | * 2、集成新浪微博SDK 51 | 52 | * 3、发帖、转发、评论 53 | 54 | * 4、微博征文布局和@某人、#话题#识别 55 | 56 | * 5、原图查看 57 | 58 | # TODO 59 | * ~~1、原图查看~~ 60 | 61 | * 2、表情显示 62 | 63 | # LICENSE 64 | 本项目基于MIT协议发布 65 | MIT: [http://rem.mit-license.org](http://rem.mit-license.org) 66 | -------------------------------------------------------------------------------- /SinaMBlog/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow* window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Category/NSString+StringValue.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+StringValue.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-14. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (StringValue) 12 | 13 | + (NSString*)getStringValue:(id)value; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Category/NSString+StringValue.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+StringValue.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-14. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "NSString+StringValue.h" 10 | 11 | @implementation NSString (StringValue) 12 | 13 | + (NSString*)getStringValue:(id)value 14 | { 15 | if (value) { 16 | if ([value isKindOfClass:[NSString class]]) { 17 | return value; 18 | } 19 | else if ([value isKindOfClass:[NSNumber class]]) { 20 | return [value stringValue]; 21 | } 22 | else { 23 | return @""; 24 | } 25 | 26 | } 27 | else { 28 | return @""; 29 | } 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /SinaMBlog/Category/UIImage+nimbusImageNamed.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+nimbusImageNamed.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/7/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (nimbusImageNamed) 12 | 13 | + (UIImage*)nimbusImageNamed:(NSString*)imageName; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Category/UIImage+nimbusImageNamed.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+nimbusImageNamed.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/7/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "UIImage+nimbusImageNamed.h" 10 | #import "UIImage+Resizing.h" 11 | 12 | @implementation UIImage (nimbusImageNamed) 13 | 14 | + (UIImage*)nimbusImageNamed:(NSString*)imageName 15 | { 16 | NSString* imagePath = NIPathForBundleResource(nil, imageName); 17 | UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath]; 18 | if (nil == image) { 19 | image = [UIImage imageWithContentsOfFile:imagePath]; 20 | // And then store it in memory. 21 | [[Nimbus imageMemoryCache] storeObject:image withName:imagePath]; 22 | } 23 | return image; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /SinaMBlog/Category/UIView+findViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+findViewController.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by ccjoy-jimneylee on 13-12-2. 6 | // Copyright (c) 2013年 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (findViewController) 12 | 13 | - (UIViewController *)viewController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Category/UIView+findViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+findViewController.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by ccjoy-jimneylee on 13-12-2. 6 | // Copyright (c) 2013年 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import "UIView+findViewController.h" 10 | 11 | @implementation UIView (findViewController) 12 | 13 | - (UIViewController *)viewController 14 | { 15 | // Traverse responder chain. Return first found view controller, which will be the view's view controller. 16 | UIResponder *responder = self; 17 | while ((responder = [responder nextResponder])) 18 | if ([responder isKindOfClass:[UIViewController class]]) 19 | return (UIViewController *)responder; 20 | 21 | // If the view controller isn't found, return nil. 22 | return nil; 23 | } 24 | 25 | @end -------------------------------------------------------------------------------- /SinaMBlog/Common/SMAPIClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // SNAPIClient.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-7-25. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLAFAPIBaseClient.h" 10 | 11 | @interface SMAPIClient : JLAFAPIBaseClient 12 | 13 | + (SMAPIClient*)sharedClient; 14 | 15 | // 用户信息 16 | + (NSString *)relativePathForUserInfoWithUserName:(NSString *)userName 17 | orUserId:(NSString *)userId; 18 | // 随便看看 19 | + (NSString*)relativePathForPublicTimelineWithPageIndex:(unsigned int)pageIndex 20 | pageSize:(unsigned int)pageSize; 21 | 22 | // 当前登录用户及关注好友微博某页 23 | + (NSString*)relativePathForFriendsTimelineWithMaxId:(NSString *)maxId; 24 | 25 | // 用户发布的微博:maxId 26 | + (NSString*)relativePathForUserTimelineWithUserID:(NSString *)userID maxId:(NSString *)maxId; 27 | 28 | // @我的微博:maxId 29 | + (NSString*)relativePathForAtMeTimelineWithMaxId:(NSString *)maxId; 30 | 31 | // 获取话题列表数据 32 | + (NSString*)relativePathForWeeklyTrendsList; 33 | 34 | //================================================================================ 35 | // status write 36 | //================================================================================ 37 | // 发送文字微博 38 | + (NSString*)relativePathForPostTextStatus; 39 | 40 | // 发送图片文字微博 41 | + (NSString*)relativePathForPostImageStatus; 42 | 43 | // 转发微博 44 | + (NSString*)relativePathForRepostStatus; 45 | 46 | // 删除微博 47 | + (NSString*)relativePathForDestroyStatus; 48 | 49 | //================================================================================ 50 | // comment wirte 51 | //================================================================================ 52 | // 发一条微博评论 53 | + (NSString*)relativePathForCreateComment; 54 | 55 | // 删除一条微博评论 56 | + (NSString*)relativePathForDestroyComment; 57 | 58 | //================================================================================ 59 | // search 60 | //================================================================================ 61 | // 搜索用户 62 | + (NSString*)urlForSearchUsersWithKeywords:(NSString*)keywords 63 | pageIndex:(unsigned int)pageIndex 64 | pageSize:(unsigned int)pageSize; 65 | 66 | // 搜索微博 67 | + (NSString*)urlForSearchStatusesWithKeywords:(NSString*)keywords 68 | pageIndex:(unsigned int)pageIndex 69 | pageSize:(unsigned int)pageSize; 70 | 71 | // 搜索话题下的微博信息 72 | + (NSString*)urlForSearchTrendsWithKeywords:(NSString*)keywords 73 | pageIndex:(unsigned int)pageIndex 74 | pageSize:(unsigned int)pageSize; 75 | 76 | @end 77 | 78 | NSString *const kSNAPIBaseURLString; -------------------------------------------------------------------------------- /SinaMBlog/Common/SMAPIClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // SNAPIClient.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-7-25. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMAPIClient.h" 10 | 11 | NSString *const kSNAPIBaseURLString = @"https://api.weibo.com/2/"; 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | /////////////////////////////////////////////////////////////////////////////////////////////////// 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | @implementation SMAPIClient 17 | 18 | /////////////////////////////////////////////////////////////////////////////////////////////////// 19 | + (SMAPIClient*)sharedClient 20 | { 21 | static SMAPIClient* _sharedClient = nil; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | _sharedClient = [[SMAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kSNAPIBaseURLString]]; 25 | }); 26 | 27 | return _sharedClient; 28 | } 29 | 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// 31 | - (id)initWithBaseURL:(NSURL *)url 32 | { 33 | self = [super initWithBaseURL:url]; 34 | if (!self) { 35 | return nil; 36 | } 37 | return self; 38 | } 39 | 40 | /////////////////////////////////////////////////////////////////////////////////////////////////// 41 | /////////////////////////////////////////////////////////////////////////////////////////////////// 42 | #pragma mark - User 43 | 44 | /////////////////////////////////////////////////////////////////////////////////////////////////// 45 | + (NSString *)relativePathForUserInfoWithUserName:(NSString *)userName 46 | orUserId:(NSString *)userId { 47 | NSString* param; 48 | if (userId.length) { 49 | param = [NSString stringWithFormat:@"uid=%@", userId]; 50 | } 51 | else if (userName.length) { 52 | param = [NSString stringWithFormat:@"screen_name=%@", userName]; 53 | } 54 | if (param) { 55 | return [NSString stringWithFormat:@"users/show.json?%@&access_token=%@", 56 | param, [SMGlobalConfig getCurrentLoginedAccessToken]]; 57 | } 58 | return nil; 59 | } 60 | 61 | /////////////////////////////////////////////////////////////////////////////////////////////////// 62 | /////////////////////////////////////////////////////////////////////////////////////////////////// 63 | #pragma mark - TimeLine 64 | 65 | /////////////////////////////////////////////////////////////////////////////////////////////////// 66 | // 公共微博某页 67 | // !note: page -> cusor 68 | + (NSString*)relativePathForPublicTimelineWithPageIndex:(unsigned int)pageIndex 69 | pageSize:(unsigned int)pageSize 70 | { 71 | return [NSString stringWithFormat:@"statuses/public_timeline.json?cursor=%d&count=%d&source=%@", 72 | pageIndex, pageSize, SinaWeiboV2AppKey]; 73 | } 74 | 75 | // 当前登录用户及关注好友微博某页 76 | + (NSString*)relativePathForFriendsTimelineWithMaxId:(NSString *)maxId 77 | { 78 | return [NSString stringWithFormat:@"statuses/friends_timeline.json?max_id=%@&access_token=%@", 79 | maxId, [SMGlobalConfig getCurrentLoginedAccessToken]]; 80 | } 81 | 82 | // 用户发布的微博:maxId 83 | + (NSString*)relativePathForUserTimelineWithUserID:(NSString *)userID maxId:(NSString *)maxId 84 | { 85 | return [NSString stringWithFormat:@"statuses/user_timeline.json?uid=%@&max_id=%@&access_token=%@", 86 | userID, maxId, [SMGlobalConfig getCurrentLoginedAccessToken]]; 87 | } 88 | 89 | // @我的微博:maxId 90 | + (NSString*)relativePathForAtMeTimelineWithMaxId:(NSString *)maxId 91 | { 92 | return [NSString stringWithFormat:@"statuses/mentions.json?max_id=%@&access_token=%@", 93 | maxId, [SMGlobalConfig getCurrentLoginedAccessToken]]; 94 | } 95 | 96 | #pragma mark - Trends 97 | 98 | // 话题列表数据 99 | + (NSString*)relativePathForWeeklyTrendsList 100 | { 101 | return [NSString stringWithFormat:@"trends/weekly.json?access_token=%@", 102 | [SMGlobalConfig getCurrentLoginedAccessToken]]; 103 | } 104 | 105 | #pragma mark - MBlog write 106 | 107 | // 发送文字微博 108 | + (NSString*)relativePathForPostTextStatus 109 | { 110 | return [NSString stringWithFormat:@"statuses/update.json"]; 111 | 112 | } 113 | 114 | // 发送图片文字微博 115 | + (NSString*)relativePathForPostImageStatus 116 | { 117 | return [NSString stringWithFormat:@"statuses/upload.json"]; 118 | } 119 | 120 | // 转发微博 121 | + (NSString*)relativePathForRepostStatus 122 | { 123 | return [NSString stringWithFormat:@"statuses/repost.json"]; 124 | } 125 | 126 | // 删除微博 127 | + (NSString*)relativePathForDestroyStatus 128 | { 129 | return [NSString stringWithFormat:@"statuses/destroy.json"]; 130 | } 131 | 132 | #pragma mark - Comment write 133 | // 评论微博 134 | + (NSString*)relativePathForCreateComment 135 | { 136 | return [NSString stringWithFormat:@"comments/create.json"]; 137 | } 138 | 139 | // 删除评论 140 | + (NSString*)relativePathForDestroyComment 141 | { 142 | return [NSString stringWithFormat:@"comments/destroy.json"]; 143 | } 144 | 145 | #pragma mark - Search 146 | // 搜索用户 147 | + (NSString*)urlForSearchUsersWithKeywords:(NSString*)keywords 148 | pageIndex:(unsigned int)pageIndex 149 | pageSize:(unsigned int)pageSize 150 | { 151 | return [NSString stringWithFormat:@"search/suggestions/users.json?q=%@&page=%d&count=%d&access_token=%@", 152 | keywords, pageIndex, pageSize, [SMGlobalConfig getCurrentLoginedAccessToken]]; 153 | } 154 | 155 | // 搜索微博 156 | + (NSString*)urlForSearchStatusesWithKeywords:(NSString*)keywords 157 | pageIndex:(unsigned int)pageIndex 158 | pageSize:(unsigned int)pageSize 159 | { 160 | return [NSString stringWithFormat:@"search/suggestions/statuses.json?q=%@&page=%d&count=%d&access_token=%@", 161 | keywords, pageIndex, pageSize, [SMGlobalConfig getCurrentLoginedAccessToken]]; 162 | } 163 | 164 | // 搜索话题下的微博信息 165 | // 高级接口待申请 http://open.weibo.com/wiki/2/search/topics 166 | + (NSString*)urlForSearchTrendsWithKeywords:(NSString*)keywords 167 | pageIndex:(unsigned int)pageIndex 168 | pageSize:(unsigned int)pageSize 169 | { 170 | return [NSString stringWithFormat:@"search/topics.json?q=%@&page=%d&count=%d&access_token=%@", 171 | keywords, pageIndex, pageSize, [SMGlobalConfig getCurrentLoginedAccessToken]]; 172 | } 173 | @end 174 | -------------------------------------------------------------------------------- /SinaMBlog/Common/SMJSONKeys.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMJSONKeys.h 3 | // SinaMBlog 4 | // 5 | // Created by Lee jimney on 7/31/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #ifndef SinaMBlog_SMJSONKeys_h 10 | #define SinaMBlog_SMJSONKeys_h 11 | 12 | // 分页获取宏 13 | #define INVALID_INDEX -1 14 | #define PERPAGE_COUNT 20 15 | 16 | //========================================================================== 17 | // 每条微博信息 18 | #define JSON_STATUS_LIST @"statuses" 19 | #define JSON_STATUS @"status" 20 | #define JSON_STATUS_CREATED_AT @"created_at" 21 | #define JSON_STATUS_ID @"id" 22 | #define JSON_STATUS_MID @"mid" 23 | #define JSON_STATUS_IDSTR @"idstr" 24 | #define JSON_STATUS_TEXT @"text" 25 | #define JSON_STATUS_SOURCE @"source" 26 | #define JSON_STATUS_FAVORITED @"favorited" 27 | #define JSON_STATUS_TRUNCATED @"truncated" 28 | #define JSON_STATUS_IN_REPLY_TO_STATUS_ID @"in_reply_to_status_id" 29 | #define JSON_STATUS_IN_REPLY_TO_USER_ID @"in_reply_to_user_id" 30 | #define JSON_STATUS_IN_REPLY_TO_SCREEN_NAME @"in_reply_to_screen_name" 31 | #define JSON_STATUS_THUMBNAIL_PIC @"thumbnail_pic" 32 | #define JSON_STATUS_BMIDDLE_PIC @"bmiddle_pic" 33 | #define JSON_STATUS_ORIGINAL_PIC @"original_pic" 34 | #define JSON_STATUS_GEO @"geo" 35 | #define JSON_STATUS_USER @"user" 36 | #define JSON_STATUS_RETWEEDTED_STATUS @"retweeted_status" 37 | #define JSON_STATUS_REPOSTS_COUNT @"reposts_count" 38 | #define JSON_STATUS_COMMENTS_COUNT @"comments_count" 39 | #define JSON_STATUS_ATTITUDES_COUNT @"attitudes_count" 40 | #define JSON_STATUS_MLEVEL @"mlevel" 41 | #define JSON_STATUS_VISIBLE @"visible" 42 | 43 | //========================================================================== 44 | // 用户信息 45 | #define JSON_USERINFO_USERID @"uid" 46 | #define JSON_USERINFO_IDSTR @"idstr" 47 | #define JSON_USERINFO_SCREEN_NAME @"screen_name" 48 | #define JSON_USERINFO_NAME @"name" 49 | #define JSON_USERINFO_GENDER @"gender" 50 | #define JSON_USERINFO_PROVINCE @"province" 51 | #define JSON_USERINFO_LOCATION @"location" 52 | #define JSON_USERINFO_DESCRIPTION @"description" 53 | #define JSON_USERINFO_URL @"url" 54 | #define JSON_USERINFO_PROFILE_IMAGE_URL @"profile_image_url" 55 | #define JSON_USERINFO_PROFILE_URL @"profile_url" 56 | #define JSON_USERINFO_FOLLOWERS_COUNT @"followers_count" 57 | #define JSON_USERINFO_FRIENDS_COUNT @"friends_count" 58 | #define JSON_USERINFO_STATUSES_COUNT @"statuses_count" 59 | #define JSON_USERINFO_FAVOURITES_COUNT @"favourites_count" 60 | #define JSON_USERINFO_FOLLOWING @"following" 61 | #define JSON_USERINFO_FOLLOW_ME @"follow_me" 62 | 63 | //========================================================================== 64 | // 话题信息 65 | #define JSON_TREND_LIST @"trends" 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/LocationManager/SMLocationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LocationViewController.h 3 | // MapKitTest 4 | // 5 | // Created by jimney on 13-3-20. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | //#import "BMapKit.h" 12 | 13 | @protocol StreetPlaceLocationDelegate 14 | - (void)deleteStreetPlace; 15 | - (void)locationUpdatedWithLatitude:(double)latitude 16 | longitude:(double)longitude 17 | streetPlace:(NSString*)streetPlace; 18 | @end 19 | 20 | @interface SMLocationViewController : UIViewController 21 | // 25 | 26 | - (id)initWithDelegate:(id)delegate; 27 | 28 | @property(nonatomic, assign) id delegate; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/LocationManager/SMLocationViewController.mm: -------------------------------------------------------------------------------- 1 | // 2 | // LocationViewController.m 3 | // SinaMBLog 4 | // 5 | // Created by jimney on 13-3-20. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMLocationViewController.h" 10 | 11 | @interface SMLocationViewController() 12 | #if 0 13 | @property(nonatomic, strong) MKMapView* mapView; 14 | @property(nonatomic, strong) BMKMapView* bMapView; 15 | @property(nonatomic, strong) BMKSearch* bmkSearch; 16 | #endif 17 | @end 18 | 19 | @implementation SMLocationViewController 20 | 21 | - (id)initWithDelegate:(id)delegate 22 | { 23 | self = [self initWithNibName:nil bundle:nil]; 24 | if (self) { 25 | self.delegate = delegate; 26 | } 27 | return self; 28 | } 29 | 30 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 31 | { 32 | self = [super initWithNibName:nil bundle:nil]; 33 | if (self) { 34 | } 35 | return self; 36 | } 37 | 38 | - (void)setRightBarButtonItemWithActivityIndicator 39 | { 40 | UIActivityIndicatorView* indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 41 | [indicator startAnimating]; 42 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:indicator]; 43 | } 44 | 45 | - (void)setRightBarButtonItemWithDeleteButton 46 | { 47 | UIImage* image = [UIImage nimbusImageNamed:@"navigationbar_button_delete_background.png"]; 48 | image = [image stretchableImageWithLeftCapWidth:image.size.width/2 topCapHeight:image.size.height/2]; 49 | UIButton* deleteBtn = [[UIButton alloc] initWithFrame:CGRectMake(0.f, 0.f, 68.f, 30.f)]; 50 | [deleteBtn setBackgroundImage:image forState:UIControlStateNormal]; 51 | [deleteBtn setTitle:@"删除位置" forState:UIControlStateNormal]; 52 | [deleteBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 53 | [deleteBtn.titleLabel setFont:[UIFont systemFontOfSize:13.f]]; 54 | [deleteBtn addTarget:self action:@selector(deleteStreetPlace) 55 | forControlEvents:UIControlEventTouchUpInside]; 56 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:deleteBtn]; 57 | 58 | } 59 | 60 | #if 0 // 暂不支持百度地图 61 | 62 | - (void)viewDidLoad 63 | { 64 | [super viewDidLoad]; 65 | 66 | self.bMapView = [[BMKMapView alloc] initWithFrame:self.view.bounds]; 67 | self.bMapView.scrollEnabled = YES; 68 | self.bMapView.delegate = self; 69 | self.bMapView.zoomLevel = 15; 70 | [self.view addSubview:self.bMapView]; 71 | self.bMapView.showsUserLocation = YES; 72 | 73 | [self setRightBarButtonItemWithActivityIndicator]; 74 | } 75 | 76 | /** 77 | *在地图View停止定位后,会调用此函数 78 | *@param mapView 地图View 79 | */ 80 | - (void)mapViewDidStopLocatingUser:(BMKMapView *)mapView { 81 | if (!_bmkSearch) { 82 | _bmkSearch = [[BMKSearch alloc] init]; 83 | _bmkSearch.delegate = self; 84 | } 85 | 86 | [_bmkSearch reverseGeocode:mapView.userLocation.coordinate]; 87 | } 88 | 89 | /** 90 | *用户位置更新后,会调用此函数 91 | *@param mapView 地图View 92 | *@param userLocation 新的用户位置 93 | */ 94 | - (void)mapView:(BMKMapView *)mapView didUpdateUserLocation:(BMKUserLocation *)userLocation { 95 | if (userLocation.location.horizontalAccuracy < 100.f) { 96 | self.bMapView.showsUserLocation = NO; 97 | } 98 | } 99 | 100 | - (void)onGetAddrResult:(BMKAddrInfo*)result errorCode:(int)error 101 | { 102 | if (error == 0) { 103 | [self locationUpdated:result.geoPt streetPlace:result.strAddr]; 104 | } else { 105 | UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil 106 | message:@"定位出现错误!" 107 | delegate:nil 108 | cancelButtonTitle:@"确定" 109 | otherButtonTitles:nil]; 110 | [av show]; 111 | } 112 | } 113 | 114 | - (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id )annotation 115 | { 116 | static NSString *AnnotationViewID = @"annotationViewID"; 117 | 118 | BMKAnnotationView *annotationView = [view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; 119 | if (annotationView == nil) { 120 | annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID]; 121 | ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed; 122 | ((BMKPinAnnotationView*)annotationView).animatesDrop = YES; 123 | } 124 | 125 | annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5)); 126 | annotationView.annotation = annotation; 127 | annotationView.canShowCallout = TRUE; 128 | [annotationView setSelected:YES animated:YES]; 129 | return annotationView; 130 | } 131 | 132 | #pragma mark Private 133 | - (void)deleteStreetPlace 134 | { 135 | if ([self.delegate respondsToSelector:@selector(deleteStreetPlace)]) { 136 | [self.delegate deleteStreetPlace]; 137 | [self.presentingViewController dismissViewControllerAnimated:YES completion:NULL]; 138 | } 139 | } 140 | 141 | #pragma mark LocationDelegate 142 | - (void)locationUpdated:(CLLocationCoordinate2D)coordinate streetPlace:(NSString*)streetPlace 143 | { 144 | BMKCoordinateRegion _region = 145 | BMKCoordinateRegionMake(coordinate, BMKCoordinateSpanMake(0.01, 0.01)); 146 | [self.bMapView setRegion:_region animated:YES]; 147 | 148 | 149 | NSArray* array = [NSArray arrayWithArray:self.bMapView.annotations]; 150 | [self.bMapView removeAnnotations:array]; 151 | 152 | BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init]; 153 | item.coordinate = coordinate; 154 | item.title = streetPlace; 155 | [self.bMapView addAnnotation:item]; 156 | 157 | [self setRightBarButtonItemWithDeleteButton]; 158 | 159 | [self.delegate locationUpdatedWithLatitude:coordinate.latitude 160 | longitude:coordinate.longitude 161 | streetPlace:streetPlace]; 162 | } 163 | #endif 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMCommentOrRetweetC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMMBlogPostC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-4. 6 | // Copyright (c) 2013年 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import "SMMBlogPostModel.h" 10 | #import "SMEmotionC.h" 11 | #import "SMPostButtonBar.h" 12 | #import "SMTrendsC.h" 13 | #import "SMFriendsC.h" 14 | 15 | typedef enum 16 | { 17 | ZDPostActionType_Comment, 18 | ZDPostActionType_Retweet 19 | }ZDPostActionType; 20 | @interface SMCommentOrRetweetC : UIViewController 22 | 23 | // 评论入口 24 | - (id)initWithBlogId:(NSString*)blogId; 25 | 26 | // 回复评论入口 27 | - (id)initWithBlogId:(NSString*)blogId replyUsername:(NSString*)username; 28 | 29 | // 转发入口 30 | - (id)initWithRetweetBlogId:(NSString*)blogId username:(NSString*)username retweetContent:(NSString*)content; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMEmotionC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMEmotionC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | @protocol SMEmotionDelegate; 10 | @interface SMEmotionC : UIViewController// 11 | { 12 | // TTScrollView* _scrollView; 13 | // TTPageControl* _pageControll; 14 | 15 | NSArray* _emotionArray; 16 | } 17 | @property (nonatomic, assign) id emotionDelegate; 18 | @end 19 | 20 | @protocol SMEmotionDelegate 21 | 22 | @optional 23 | - (void)emotionSelectedWithCode:(NSString*)code; 24 | 25 | @end 26 | 27 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMEmotionC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMEmotionC.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMEmotionC.h" 10 | #import "SMEmotionEntity.h" 11 | 12 | #define MARGIN 25 13 | #define ROW_COUNT 4 14 | #define COLUMN_COUNT 7 15 | #define SPACE 10 16 | #define FACE_WIDTH 30 17 | #define PAGE_CONTROL_HEIGHT 20 18 | 19 | @implementation SMEmotionC 20 | 21 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 22 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 23 | { 24 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 25 | if (self) { 26 | _emotionArray = [SMGlobalConfig emotionsArray]; 27 | } 28 | return self; 29 | } 30 | 31 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 32 | - (void)loadView 33 | { 34 | [super loadView]; 35 | self.view.backgroundColor = [UIColor clearColor]; 36 | 37 | // _scrollView = [[TTScrollView alloc] initWithFrame:self.view.bounds]; 38 | // _scrollView.backgroundColor = [UIColor clearColor]; 39 | // _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 40 | // _scrollView.zoomEnabled = NO; 41 | // _scrollView.pageSpacing = 20.f; 42 | // _scrollView.delegate = self; 43 | // _scrollView.dataSource = self; 44 | // [self.view addSubview:_scrollView]; 45 | // 46 | // _pageControll = [[TTPageControl alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - PAGE_CONTROL_HEIGHT, 47 | // self.view.bounds.size.width, PAGE_CONTROL_HEIGHT)]; 48 | // [_pageControll addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged]; 49 | // _pageControll.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; 50 | // [self.view addSubview:_pageControll]; 51 | } 52 | 53 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 54 | - (void)viewDidLoad 55 | { 56 | [super viewDidLoad]; 57 | // Do any additional setup after loading the view. 58 | } 59 | 60 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 61 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 62 | #pragma mark - TTScrollViewDataSource 63 | 64 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 65 | //- (NSInteger)numberOfPagesInScrollView:(TTScrollView*)scrollView 66 | //{ 67 | // int numInPage = ROW_COUNT * COLUMN_COUNT; 68 | // int pageNum = ceil((float)_emotionArray.count / numInPage); 69 | // [_pageControll setNumberOfPages:pageNum]; 70 | // return pageNum; 71 | //} 72 | // 73 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 74 | //- (UIView*)scrollView:(TTScrollView*)scrollView pageAtIndex:(NSInteger)pageIndex 75 | //{ 76 | // int row = ROW_COUNT; 77 | // int column = COLUMN_COUNT; 78 | // 79 | // TTView* pageView = (TTView*)[scrollView dequeueReusablePage]; 80 | // if (pageView == nil) { 81 | // pageView = [[[TTView alloc] initWithFrame:CGRectMake(0, 0, column * (FACE_WIDTH + SPACE), 82 | // row * (FACE_WIDTH + SPACE))] autorelease]; 83 | // pageView.backgroundColor = [UIColor clearColor]; 84 | // 85 | // UITapGestureRecognizer* gest = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(faceTaped:)]; 86 | // [pageView addGestureRecognizer:[gest autorelease]]; 87 | // } 88 | // for (int i = 0; i < row; i++) { 89 | // for (int j = 0; j < column; j++) { 90 | // TTImageView* imgView = (TTImageView*)[pageView viewWithTag:9 + i*column +j]; 91 | // if (row*column*pageIndex + i*column + j < _emotionArray.count) { 92 | // SMEmotionEntity* entity = [_emotionArray objectAtIndex:row*column*pageIndex + i*column + j]; 93 | // if (imgView == nil) { 94 | // imgView = [[TTImageView alloc] initWithFrame:CGRectMake(j*(FACE_WIDTH + SPACE) + MARGIN, 95 | // i*(FACE_WIDTH + SPACE) + MARGIN, 96 | // FACE_WIDTH, FACE_WIDTH)]; 97 | // imgView.tag = 9 + i*column +j; 98 | // imgView.backgroundColor = [UIColor clearColor]; 99 | // [pageView addSubview:[imgView autorelease]]; 100 | // } 101 | // [imgView unsetImage]; 102 | // imgView.urlPath = entity.urlPath; 103 | // } 104 | // else { 105 | // [imgView removeFromSuperview]; 106 | // } 107 | // } 108 | // } 109 | // 110 | // return pageView; 111 | //} 112 | // 113 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 114 | //- (CGSize)scrollView:(TTScrollView*)scrollView sizeOfPageAtIndex:(NSInteger)pageIndex 115 | //{ 116 | // return CGSizeZero; 117 | //} 118 | // 119 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 120 | //- (void)scrollView:(TTScrollView*)scrollView didMoveToPageAtIndex:(NSInteger)pageIndex 121 | //{ 122 | // [_pageControll setCurrentPage:pageIndex]; 123 | //} 124 | // 125 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 126 | //- (void)pageChanged:(id)sender 127 | //{ 128 | // TTPageControl* ctrl = sender; 129 | // [_scrollView setCenterPageIndex:ctrl.currentPage]; 130 | //} 131 | // 132 | //////////////////////////////////////////////////////////////////////////////////////////////////////// 133 | ////todo:考虑touch move down来模拟选择 134 | //- (void)faceTaped:(UIGestureRecognizer*)gest 135 | //{ 136 | // CGPoint point = [gest locationInView:_scrollView]; 137 | // // NSLog(@"lo: %f, %f", point.x, point.y); 138 | // int row = ROW_COUNT;//floor(_scrollView.bounds.size.height / FACE_WIDTH); 139 | // int column = COLUMN_COUNT;//floor(_scrollView.bounds.size.width / FACE_WIDTH); 140 | // 141 | // int currentRow = floor((point.y - MARGIN) / (FACE_WIDTH+SPACE)); 142 | // int currentcolumn = floor((point.x - MARGIN) / (FACE_WIDTH + SPACE)); 143 | //#ifdef DEBUG 144 | // NSLog(@"row = %d, column = %d", currentRow, currentcolumn); 145 | //#endif 146 | // int index = row*column*_scrollView.centerPageIndex + column* currentRow + currentcolumn; 147 | // if (index < _emotionArray.count) { 148 | // if ([self.emotionDelegate respondsToSelector:@selector(emotionSelectedWithCode:)]) { 149 | // [self.emotionDelegate emotionSelectedWithCode:[(SMEmotionEntity*)[_emotionArray objectAtIndex:index] code]]; 150 | // } 151 | // } 152 | //} 153 | 154 | @end 155 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMFriendsC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendsC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableViewController.h" 10 | 11 | @class SMFriendEntity; 12 | @protocol SMFriendsDelegate; 13 | @interface SMFriendsC : JLNimbusTableViewController 14 | 15 | @property(nonatomic, assign) id friendsDelegate; 16 | 17 | @end 18 | 19 | @protocol SMFriendsDelegate 20 | 21 | - (void)didSelectAFriend:(SMFriendEntity*)user; 22 | 23 | @end -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMFriendsC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendsC.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMFriendsC.h" 10 | #import "SMFriendsModel.h" 11 | #import "SMFriendEntity.h" 12 | 13 | @interface SMFriendsC () 14 | 15 | @end 16 | 17 | @implementation SMFriendsC 18 | 19 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 20 | /////////////////////////////////////////////////////////////////////////////////////////////////// 21 | #pragma mark - UIView 22 | 23 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 24 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 25 | { 26 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 27 | if (self) { 28 | self.title = @"联系人"; 29 | } 30 | return self; 31 | } 32 | 33 | /////////////////////////////////////////////////////////////////////////////////////////////////// 34 | /////////////////////////////////////////////////////////////////////////////////////////////////// 35 | #pragma mark - Override 36 | 37 | /////////////////////////////////////////////////////////////////////////////////////////////////// 38 | - (id)tableModelClass 39 | { 40 | return [SMFriendsModel class]; 41 | } 42 | 43 | /////////////////////////////////////////////////////////////////////////////////////////////////// 44 | - (NIActionBlock)tapAction 45 | { 46 | return ^BOOL(id object, id target, NSIndexPath* indexPath) { 47 | if (!self.editing) { 48 | if ([object isKindOfClass:[SMFriendEntity class]]) { 49 | SMFriendEntity* entity = (SMFriendEntity*)object; 50 | if ([self.friendsDelegate respondsToSelector:@selector(didSelectAFriend:)]) { 51 | [self.friendsDelegate didSelectAFriend:entity]; 52 | [self.navigationController popViewControllerAnimated:YES]; 53 | } 54 | } 55 | return YES; 56 | } 57 | else { 58 | return NO; 59 | } 60 | }; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMHomeTimlineListC.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLNimbusTableViewController.h" 11 | 12 | @interface SMHomeTimlineListC : JLNimbusTableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMHomeTimlineListC.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMHomeTimlineListC.h" 10 | #import "SMStatusEntity.h" 11 | #import "SMMaxIdTimelineTypeModel.h" 12 | #import "SMUserInfoModel.h" 13 | #import "SMMBlogPostC.h" 14 | 15 | @interface SMHomeTimlineListC () 16 | @property (nonatomic, strong) NIActionBlock tapAction; 17 | @end 18 | 19 | @implementation SMHomeTimlineListC 20 | 21 | /////////////////////////////////////////////////////////////////////////////////////////////////// 22 | /////////////////////////////////////////////////////////////////////////////////////////////////// 23 | #pragma mark - UIViewController 24 | 25 | /////////////////////////////////////////////////////////////////////////////////////////////////// 26 | - (id)initWithStyle:(UITableViewStyle)style 27 | { 28 | self = [super initWithStyle:style]; 29 | if (self) { 30 | self.navigationItem.leftBarButtonItem = [SMGlobalConfig createPostBarButtonItemWithTarget:self 31 | action:@selector(postNewStatusAction)]; 32 | self.navigationItem.rightBarButtonItem = [SMGlobalConfig createRefreshBarButtonItemWithTarget:self 33 | action:@selector(autoPullDownRefreshActionAnimation)]; 34 | [self showTitleWithUserName]; 35 | } 36 | return self; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (void)viewDidLoad 41 | { 42 | [super viewDidLoad]; 43 | 44 | self.tableView.separatorColor = [UIColor clearColor]; 45 | self.tableView.backgroundColor = TABLE_VIEW_BG_COLOR; 46 | self.tableView.backgroundView = nil; 47 | } 48 | 49 | /////////////////////////////////////////////////////////////////////////////////////////////////// 50 | - (void)didReceiveMemoryWarning 51 | { 52 | [super didReceiveMemoryWarning]; 53 | // Dispose of any resources that can be recreated. 54 | } 55 | 56 | /////////////////////////////////////////////////////////////////////////////////////////////////// 57 | /////////////////////////////////////////////////////////////////////////////////////////////////// 58 | #pragma mark - Private 59 | 60 | /////////////////////////////////////////////////////////////////////////////////////////////////// 61 | - (void)postNewStatusAction 62 | { 63 | SMMBlogPostC* postC = [[SMMBlogPostC alloc] init]; 64 | [self.navigationController pushViewController:postC animated:YES]; 65 | } 66 | 67 | /////////////////////////////////////////////////////////////////////////////////////////////////// 68 | // 获取当前登录用户的基本信息 69 | - (void)showTitleWithUserName 70 | { 71 | if ([SMGlobalConfig getCurrentLoginedUserName].length) { 72 | self.title = [SMGlobalConfig getCurrentLoginedUserName]; 73 | } 74 | else if ([SMGlobalConfig getCurrentLoginedUserId].length) { 75 | SMUserInfoModel* userInfoModel = [[SMUserInfoModel alloc] init]; 76 | [userInfoModel loadUserInfoWithUserName:nil orUserId:[SMGlobalConfig getCurrentLoginedUserId] 77 | block:^(SMUserInfoEntity *entity, NSError *error) { 78 | if (entity) { 79 | self.title = entity.name; 80 | [SMGlobalConfig setCurrentLoginedUserName:entity.name]; 81 | } 82 | }]; 83 | } 84 | } 85 | 86 | /////////////////////////////////////////////////////////////////////////////////////////////////// 87 | /////////////////////////////////////////////////////////////////////////////////////////////////// 88 | #pragma mark - Override 89 | 90 | /////////////////////////////////////////////////////////////////////////////////////////////////// 91 | - (id)tableModelClass 92 | { 93 | return [SMMaxIdTimelineTypeModel class]; 94 | } 95 | 96 | /////////////////////////////////////////////////////////////////////////////////////////////////// 97 | - (NIActionBlock)tapAction 98 | { 99 | return ^BOOL(id object, id target, NSIndexPath* indexPath) { 100 | if (!self.editing) { 101 | if ([object isKindOfClass:[SMStatusEntity class]]) { 102 | SMStatusEntity* status = (SMStatusEntity*)object; 103 | [SMGlobalConfig showHUDMessage:status.source addedToView:self.view]; 104 | } 105 | return YES; 106 | } 107 | else { 108 | return NO; 109 | } 110 | }; 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMLoginC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SNUserCenterC.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-7-25. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SMLoginC : UITableViewController 12 | 13 | @end 14 | NSString *const SNDidOAuthNotification; -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMLoginC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SNUserCenterC.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-7-25. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMLoginC.h" 10 | #import "NimbusModels.h" 11 | #import "NimbusCore.h" 12 | 13 | #import "SMPageTimlineListC.h" 14 | #import "SMHomeTimlineListC.h" 15 | #import "SMAuthorizeModel.h" 16 | 17 | NSString *const SNDidOAuthNotification = @"DidOAuthNotification"; 18 | 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | /////////////////////////////////////////////////////////////////////////////////////////////////// 21 | /////////////////////////////////////////////////////////////////////////////////////////////////// 22 | @interface SMLoginC () 23 | 24 | @property (nonatomic, readwrite, retain) NITableViewModel* model; 25 | @property (nonatomic, readwrite, retain) NITableViewActions* actions; 26 | @property (nonatomic, readwrite, retain) NICellFactory* cellFactory; 27 | @property (nonatomic, strong) __block MBProgressHUD* hud; 28 | 29 | @end 30 | 31 | /////////////////////////////////////////////////////////////////////////////////////////////////// 32 | /////////////////////////////////////////////////////////////////////////////////////////////////// 33 | /////////////////////////////////////////////////////////////////////////////////////////////////// 34 | @implementation SMLoginC 35 | 36 | /////////////////////////////////////////////////////////////////////////////////////////////////// 37 | - (id)initWithStyle:(UITableViewStyle)style { 38 | self = [super initWithStyle:style]; 39 | if (self) { 40 | // Custom initialization 41 | self.title = @"新浪微博"; 42 | 43 | _actions = [[NITableViewActions alloc] initWithTarget:self]; 44 | NIActionBlock tapLoginAction = 45 | ^BOOL(id object, UIViewController *controller, NSIndexPath* indexPath) { 46 | if ([SMAuthorizeModel isAuthorized]) { 47 | [self showHomeView]; 48 | } 49 | else { 50 | if (!self.hud) {// 已登录ing,不执行登录操作 51 | [SMAuthorizeModel sendAuthorizeRequest]; 52 | self.hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 53 | self.hud.labelText = @"正在登录..."; 54 | return YES; 55 | } 56 | } 57 | 58 | return NO; 59 | }; 60 | 61 | NIActionBlock tapPublicAction = ^BOOL(id object, UIViewController *controller, NSIndexPath* indexPath) { 62 | SMPageTimlineListC* c = [[SMPageTimlineListC alloc] init]; 63 | [controller.navigationController pushViewController:c animated:YES]; 64 | return YES; 65 | }; 66 | NSArray* tableContents = 67 | [NSArray arrayWithObjects: 68 | @"", 69 | [_actions attachToObject:[NITitleCellObject objectWithTitle:@"登录微博"] 70 | tapBlock:tapLoginAction], 71 | @"", 72 | [_actions attachToObject:[NITitleCellObject objectWithTitle:@"随便看看"] 73 | tapBlock:tapPublicAction], 74 | nil]; 75 | 76 | _cellFactory = [[NICellFactory alloc] init]; 77 | [_cellFactory mapObjectClass:[NITitleCellObject class] 78 | toCellClass:[NITextCell class]]; 79 | _model = [[NITableViewModel alloc] initWithSectionedArray:tableContents 80 | delegate:_cellFactory]; 81 | 82 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didOAuthNotification:) 83 | name:SNDidOAuthNotification object:nil]; 84 | } 85 | return self; 86 | } 87 | 88 | /////////////////////////////////////////////////////////////////////////////////////////////////// 89 | /////////////////////////////////////////////////////////////////////////////////////////////////// 90 | #pragma mark UIViewController 91 | 92 | /////////////////////////////////////////////////////////////////////////////////////////////////// 93 | - (void)viewWillAppear:(BOOL)animated 94 | { 95 | [super viewWillAppear:animated]; 96 | } 97 | 98 | /////////////////////////////////////////////////////////////////////////////////////////////////// 99 | - (void)viewDidLoad 100 | { 101 | [super viewDidLoad]; 102 | 103 | self.tableView.dataSource = self.model; 104 | self.tableView.delegate = [self.actions forwardingTo:self]; 105 | 106 | self.tableView.backgroundColor = TABLE_VIEW_BG_COLOR; 107 | self.tableView.backgroundView = nil; 108 | } 109 | 110 | /////////////////////////////////////////////////////////////////////////////////////////////////// 111 | - (void)didReceiveMemoryWarning 112 | { 113 | [super didReceiveMemoryWarning]; 114 | // Dispose of any resources that can be recreated. 115 | } 116 | 117 | /////////////////////////////////////////////////////////////////////////////////////////////////// 118 | /////////////////////////////////////////////////////////////////////////////////////////////////// 119 | #pragma mark - Private 120 | 121 | /////////////////////////////////////////////////////////////////////////////////////////////////// 122 | - (void)showHomeView 123 | { 124 | SMHomeTimlineListC* c = [[SMHomeTimlineListC alloc] init]; 125 | [self.navigationController pushViewController:c animated:YES]; 126 | } 127 | 128 | /////////////////////////////////////////////////////////////////////////////////////////////////// 129 | /////////////////////////////////////////////////////////////////////////////////////////////////// 130 | #pragma mark - SNDidOAuthNotification 131 | 132 | /////////////////////////////////////////////////////////////////////////////////////////////////// 133 | - (void)didOAuthNotification:(NSNotification*)notify 134 | { 135 | id object = notify.object; 136 | if ([object isKindOfClass:[NSNumber class]]) { 137 | BOOL authoredSuccess = [(NSNumber*)object boolValue]; 138 | if (authoredSuccess) { 139 | [self showHomeView]; 140 | } 141 | else { 142 | self.hud.labelText = @"登录失败"; 143 | [self.hud hide:YES afterDelay:1.0f]; 144 | self.hud = nil; 145 | } 146 | } 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMMBlogPostC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMMBlogPostC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-4. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMMBlogPostModel.h" 10 | #import "SMEmotionC.h" 11 | #import "SMPostButtonBar.h" 12 | #import "SMPostPhotoBrowseC.h" 13 | #import "SMTrendsC.h" 14 | #import "SMFriendsC.h" 15 | #import "SMLocationViewController.h" 16 | 17 | @interface SMMBlogPostC : UIViewController 22 | @property (nonatomic, retain) UIImage* image; 23 | @property (nonatomic, copy) NSString* streetPlace; 24 | 25 | // 发表关于某个话题微博 26 | - (id)initWithTrendName:(NSString*)trend; 27 | 28 | // 发表@某人微博 29 | - (id)initWithUserName:(NSString*)username; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPageTimlineListC.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableViewController.h" 10 | 11 | @interface SMPageTimlineListC : JLNimbusTableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPageTimlineListC.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPageTimlineListC.h" 10 | #import "SMStatusEntity.h" 11 | #import "SMPageTimelineModel.h" 12 | 13 | @interface SMPageTimlineListC () 14 | @property (nonatomic, assign) NIActionBlock tapAction; 15 | @end 16 | 17 | @implementation SMPageTimlineListC 18 | 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | /////////////////////////////////////////////////////////////////////////////////////////////////// 21 | #pragma mark - UIViewController 22 | 23 | /////////////////////////////////////////////////////////////////////////////////////////////////// 24 | - (id)initWithStyle:(UITableViewStyle)style 25 | { 26 | self = [super initWithStyle:style]; 27 | if (self) { 28 | self.title = APP_NAME; 29 | self.navigationItem.rightBarButtonItem = [SMGlobalConfig createRefreshBarButtonItemWithTarget:self 30 | action:@selector(autoPullDownRefreshActionAnimation)]; 31 | } 32 | return self; 33 | } 34 | 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// 36 | - (void)viewDidLoad 37 | { 38 | [super viewDidLoad]; 39 | 40 | self.tableView.separatorColor = [UIColor clearColor]; 41 | self.tableView.backgroundColor = TABLE_VIEW_BG_COLOR; 42 | self.tableView.backgroundView = nil; 43 | } 44 | 45 | /////////////////////////////////////////////////////////////////////////////////////////////////// 46 | - (void)didReceiveMemoryWarning 47 | { 48 | [super didReceiveMemoryWarning]; 49 | // Dispose of any resources that can be recreated. 50 | } 51 | 52 | /////////////////////////////////////////////////////////////////////////////////////////////////// 53 | /////////////////////////////////////////////////////////////////////////////////////////////////// 54 | #pragma mark - Private 55 | 56 | 57 | /////////////////////////////////////////////////////////////////////////////////////////////////// 58 | /////////////////////////////////////////////////////////////////////////////////////////////////// 59 | #pragma mark - Override 60 | 61 | /////////////////////////////////////////////////////////////////////////////////////////////////// 62 | - (id)tableModelClass 63 | { 64 | return [SMPageTimelineModel class]; 65 | } 66 | 67 | /////////////////////////////////////////////////////////////////////////////////////////////////// 68 | - (NIActionBlock)tapAction 69 | { 70 | return ^BOOL(id object, id target, NSIndexPath* indexPath) { 71 | if (!self.editing) { 72 | if ([object isKindOfClass:[SMStatusEntity class]]) { 73 | SMStatusEntity* status = (SMStatusEntity*)object; 74 | [SMGlobalConfig showHUDMessage:status.source addedToView:self.view]; 75 | } 76 | return YES; 77 | } 78 | else { 79 | return NO; 80 | } 81 | }; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPhotoBrowseC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPhotoBrowseC.h 3 | // DSL 4 | // 5 | // Created by jimney Lee on 10/11/12. 6 | // Copyright (c) 2012 jimneylee. All rights reserved. 7 | // 8 | 9 | 10 | @interface SMPhotoBrowseC : UIViewController 11 | 12 | - (id)initWithUrlPath:(NSString*)urlPath; 13 | - (id)initWithImage:(UIImage*)image; 14 | 15 | @property (nonatomic, copy) NSString* urlPath; 16 | @property (nonatomic, strong) UIImage* image; 17 | @property (nonatomic, strong) UIScrollView* scrollView; 18 | @property (nonatomic, strong) NINetworkImageView* imageView; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPhotoBrowseC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPhotoBrowseC.m 3 | // DSL 4 | // 5 | // Created by jimney Lee on 10/11/12. 6 | // Copyright (c) 2012 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPhotoBrowseC.h" 10 | 11 | @interface SMPhotoBrowseC () 12 | 13 | @end 14 | 15 | @implementation SMPhotoBrowseC 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | - (id)initWithUrlPath:(NSString*)urlPath 19 | { 20 | self = [self initWithNibName:nil bundle:nil]; 21 | if (self) { 22 | self.urlPath = urlPath; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | /////////////////////////////////////////////////////////////////////////////////////////////////// 29 | - (id)initWithImage:(UIImage*)image 30 | { 31 | self = [self initWithNibName:nil bundle:nil]; 32 | if (self) { 33 | self.image = image; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 41 | { 42 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 43 | if (self) { 44 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"保存" 45 | style:UIBarButtonItemStylePlain 46 | target:self action:@selector(save)]; 47 | 48 | 49 | } 50 | 51 | return self; 52 | } 53 | 54 | /////////////////////////////////////////////////////////////////////////////////////////////////// 55 | /////////////////////////////////////////////////////////////////////////////////////////////////// 56 | #pragma mark - UIView 57 | 58 | /////////////////////////////////////////////////////////////////////////////////////////////////// 59 | - (void)loadView 60 | { 61 | [super loadView]; 62 | self.view.backgroundColor = [UIColor blackColor]; 63 | 64 | CGRect frame = CGRectMake(0, 0, self.view.width, [UIScreen mainScreen].bounds.size.height 65 | - NIStatusBarHeight() - NIToolbarHeightForOrientation(self.interfaceOrientation)); 66 | 67 | _scrollView = [[UIScrollView alloc] initWithFrame:frame]; 68 | _scrollView.delegate = self; 69 | _scrollView.zoomScale = 1.0; 70 | _scrollView.minimumZoomScale = 1.0; 71 | _scrollView.maximumZoomScale = 2.0f; 72 | _scrollView.backgroundColor = [UIColor clearColor]; 73 | [self.view addSubview:_scrollView]; 74 | 75 | _imageView = [[NINetworkImageView alloc] initWithFrame:_scrollView.bounds]; 76 | _imageView.backgroundColor = [UIColor clearColor]; 77 | [_scrollView addSubview:_imageView]; 78 | 79 | if (self.urlPath) { 80 | [_imageView setPathToNetworkImage:self.urlPath]; 81 | } 82 | else if (self.image) { 83 | _imageView.initialImage = self.image; 84 | } 85 | } 86 | 87 | /////////////////////////////////////////////////////////////////////////////////////////////////// 88 | /////////////////////////////////////////////////////////////////////////////////////////////////// 89 | #pragma mark - Private 90 | 91 | /////////////////////////////////////////////////////////////////////////////////////////////////// 92 | - (void)save 93 | { 94 | if (_imageView.image) { 95 | UIImageWriteToSavedPhotosAlbum(_imageView.image, nil, nil, nil); 96 | // TODO: show asyn 97 | [SMGlobalConfig showHUDMessage:@"保存成功!" addedToView:self.view]; 98 | } 99 | } 100 | 101 | /////////////////////////////////////////////////////////////////////////////////////////////////// 102 | /////////////////////////////////////////////////////////////////////////////////////////////////// 103 | #pragma mark UIScrolViewDelegate 104 | 105 | /////////////////////////////////////////////////////////////////////////////////////////////////// 106 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 107 | { 108 | return _imageView; 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPostPhotoBrowseC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPostPhotoBrowseC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-7. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPhotoBrowseC.h" 10 | 11 | @protocol ZDPostPhotoBrowseDelegate; 12 | @interface SMPostPhotoBrowseC : SMPhotoBrowseC 13 | 14 | @property (nonatomic, assign) id deletePhotoDelegate; 15 | 16 | @end 17 | 18 | @protocol ZDPostPhotoBrowseDelegate 19 | @optional 20 | - (void)deletePhoto; 21 | @end -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMPostPhotoBrowseC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPostPhotoBrowseC.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-7. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPostPhotoBrowseC.h" 10 | 11 | @interface SMPostPhotoBrowseC () 12 | 13 | @end 14 | 15 | @implementation SMPostPhotoBrowseC 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | self.navigationItem.rightBarButtonItem = [SMGlobalConfig createBarButtonItemWithTitle:@"删除照片" 23 | target:self 24 | action:@selector(deletePhoto)]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// 31 | - (void)deletePhoto 32 | { 33 | if ([self.deletePhotoDelegate respondsToSelector:@selector(deletePhoto)]) { 34 | [self.deletePhotoDelegate deletePhoto]; 35 | } 36 | [self.navigationController popViewControllerAnimated:YES]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMTrendsC.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendsC.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableViewController.h" 10 | 11 | @protocol SMTrendsDelegate; 12 | @interface SMTrendsC : JLNimbusTableViewController 13 | 14 | @property(nonatomic, assign) id trendsDelegate; 15 | 16 | @end 17 | 18 | @protocol SMTrendsDelegate 19 | 20 | - (void)didSelectATrend:(NSString*)trend; 21 | 22 | @end -------------------------------------------------------------------------------- /SinaMBlog/Controllers/SMTrendsC.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendsC.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMTrendsC.h" 10 | #import "SMTrendsModel.h" 11 | #import "SMTrendEntity.h" 12 | 13 | @interface SMTrendsC () 14 | 15 | @end 16 | 17 | @implementation SMTrendsC 18 | 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 21 | { 22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 23 | if (self) { 24 | self.title = @"插入话题"; 25 | // self.navigationItem.leftBarButtonItem = 26 | // [SMGlobalConfig createBarButtonItemWithTitle:@"关闭" 27 | // target:self 28 | // action:@selector(dismissViewControllerAnimated:completion:)]; 29 | } 30 | return self; 31 | } 32 | 33 | /////////////////////////////////////////////////////////////////////////////////////////////////// 34 | /////////////////////////////////////////////////////////////////////////////////////////////////// 35 | #pragma mark - Override 36 | 37 | /////////////////////////////////////////////////////////////////////////////////////////////////// 38 | - (id)tableModelClass 39 | { 40 | return [SMTrendsModel class]; 41 | } 42 | 43 | /////////////////////////////////////////////////////////////////////////////////////////////////// 44 | - (NIActionBlock)tapAction 45 | { 46 | return ^BOOL(id object, id target, NSIndexPath* indexPath) { 47 | if (!self.editing) { 48 | if ([object isKindOfClass:[SMTrendEntity class]]) { 49 | SMTrendEntity* entity = (SMTrendEntity*)object; 50 | if ([self.trendsDelegate respondsToSelector:@selector(didSelectATrend:)]) { 51 | [self.trendsDelegate didSelectATrend:[entity getNameWithSharp]]; 52 | [self.navigationController popViewControllerAnimated:YES]; 53 | } 54 | } 55 | return YES; 56 | } 57 | else { 58 | return NO; 59 | } 60 | }; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /SinaMBlog/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Default-568h@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Default.png -------------------------------------------------------------------------------- /SinaMBlog/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Default@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMEmotionEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMEmotionEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SMEmotionEntity : NSObject 12 | { 13 | NSString* _code; 14 | NSString* _urlPath; 15 | } 16 | 17 | + (id)entityWithDictionary:(NSDictionary*)dic; 18 | + (id)entityWithDictionaryForHtml:(NSDictionary *)dic; 19 | @property (nonatomic, copy) NSString* code; 20 | @property (nonatomic, copy) NSString* urlPath; 21 | @end 22 | 23 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMEmotionEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMEmotionEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMEmotionEntity.h" 10 | 11 | @implementation SMEmotionEntity 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | + (id)entityWithDictionary:(NSDictionary*)dic 15 | { 16 | SMEmotionEntity* entity = [SMEmotionEntity new]; 17 | entity.code = [NSString stringWithFormat:@"[%@]", [dic objectForKey:@"chs"]]; 18 | NSString* name = [dic objectForKey:@"gif"]; 19 | entity.urlPath = [NSString stringWithFormat:@"bundle://%@", name]; 20 | return entity; 21 | } 22 | 23 | /////////////////////////////////////////////////////////////////////////////////////////////////// 24 | + (id)entityWithDictionaryForHtml:(NSDictionary *)dic { 25 | SMEmotionEntity* entity = [SMEmotionEntity new]; 26 | entity.code = [NSString stringWithFormat:@"[%@]", [dic objectForKey:@"chs"]]; 27 | NSString* name = [dic objectForKey:@"gif"]; 28 | entity.urlPath = name; 29 | return entity; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMFriendEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionItemBaseEntity.h" 10 | 11 | @interface SMFriendEntity : SMSectionItemBaseEntity 12 | 13 | @property (nonatomic, copy) NSString* userId; 14 | 15 | + (id)entityWithDictionary:(NSDictionary*)dic; 16 | - (NSString* )getNameWithAt; 17 | @end 18 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMFriendEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMFriendEntity.h" 10 | #import "NSString+StringValue.h" 11 | #import "pinyin.h" 12 | 13 | @implementation SMFriendEntity 14 | @synthesize userId = _userId; 15 | 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | + (id)entityWithDictionary:(NSDictionary*)dic 18 | { 19 | SMFriendEntity* entity = [SMFriendEntity new]; 20 | entity.userId = [NSString getStringValue:[dic objectForKey:@"id"]]; 21 | entity.name = [dic objectForKey:@"name"]; 22 | 23 | if (entity.name.length > 0) { 24 | entity.sortString = [entity createSortString]; 25 | return entity; 26 | } 27 | else return nil; 28 | } 29 | 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// 31 | #pragma mark Public 32 | - (NSString* )getNameWithAt 33 | { 34 | return [NSString stringWithFormat:@"@%@", self.name]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMFriendListEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendsEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionListBaseEntity.h" 10 | 11 | @interface SMFriendListEntity :SMSectionListBaseEntity 12 | 13 | + (id)entityWithDictionary:(NSDictionary*)dic; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMFriendListEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendsEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMFriendListEntity.h" 10 | #import "SMFriendEntity.h" 11 | 12 | @implementation SMFriendListEntity 13 | 14 | // http://open.weibo.com/wiki/2/friendships/groups 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | + (id)entityWithDictionary:(NSDictionary*)dic 17 | { 18 | SMFriendListEntity* entity = [SMFriendListEntity new]; 19 | NSArray* sourceArray = [dic objectForKey:@"lists"]; 20 | if (sourceArray.count > 0) { 21 | 22 | entity.unsortedArray = [NSMutableArray arrayWithCapacity:sourceArray.count]; 23 | for (NSDictionary* d in sourceArray) { 24 | SMFriendEntity* e = [SMFriendEntity entityWithDictionary:d]; 25 | if (e) { 26 | [entity.unsortedArray addObject:e]; 27 | } 28 | } 29 | 30 | [entity sort]; 31 | } 32 | return entity; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMSectionItemBaseEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMSectionItemEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | @interface SMSectionItemBaseEntity : NISubtitleCellObject 10 | { 11 | NSString* _name; 12 | unichar _firstLetter; // 首字母 13 | NSString* _sortString; // 供排序所用字串 14 | } 15 | 16 | - (NSString* )createSortString; 17 | 18 | @property (nonatomic, copy) NSString* name; 19 | @property (nonatomic, copy) NSString* sortString; 20 | @property (nonatomic) unichar firstLetter; 21 | @end 22 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMSectionItemBaseEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMSectionItemEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionItemBaseEntity.h" 10 | #import "pinyin.h" 11 | 12 | @implementation SMSectionItemBaseEntity 13 | @synthesize name = _name, sortString = _sortString, firstLetter = _firstLetter; 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | #pragma mark Private 18 | 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | - (NSString* )createSortString 21 | { 22 | NSMutableString* sortedString = [NSMutableString string]; 23 | unichar aChar; 24 | unichar pinyinChar; 25 | for (int i = 0; i < self.name.length; i++) { 26 | aChar = [self.name characterAtIndex:i]; 27 | // 判断首字母是否为英文 28 | if ((aChar >= 'A' && aChar <= 'Z') || 29 | (aChar >= 'a' && aChar <= 'z') ) { 30 | [sortedString appendString:[NSString stringWithFormat:@"%c", aChar]]; 31 | if (0 == i) { 32 | self.firstLetter = [[[NSString stringWithFormat:@"%c", aChar] uppercaseString] characterAtIndex:0]; 33 | } 34 | } 35 | // 判断首字母是否为汉子 36 | else if (isFirstLetterHANZI(aChar)) { 37 | pinyinChar = pinyinFirstLetter(aChar); 38 | [sortedString appendString:[NSString stringWithFormat:@"%c", pinyinChar + 26]]; 39 | if (0 == i) { 40 | self.firstLetter= [[[NSString stringWithFormat:@"%c", pinyinChar] uppercaseString] characterAtIndex:0]; 41 | } 42 | } 43 | // 为其他非字母和汉子字符 44 | else { 45 | if (0 == i) { 46 | self.firstLetter = '#'; 47 | } 48 | } 49 | } 50 | return sortedString; 51 | } 52 | 53 | /////////////////////////////////////////////////////////////////////////////////////////////////// 54 | - (NSComparisonResult)compare:(SMSectionItemBaseEntity*)other 55 | { 56 | return [self.sortString compare:other.sortString]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMSectionListBaseEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMSectionListBaseEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SMSectionListBaseEntity : NSObject 12 | { 13 | NSMutableArray* _unsortedArray; 14 | NSMutableArray* _sections; 15 | NSMutableArray* _items; 16 | } 17 | 18 | - (void)sort; 19 | 20 | @property (nonatomic, retain) NSMutableArray* unsortedArray; 21 | @property (nonatomic, retain) NSMutableArray* sections; 22 | @property (nonatomic, retain) NSMutableArray* items; 23 | @end 24 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMSectionListBaseEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMSectionListBaseEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionListBaseEntity.h" 10 | #import "SMSectionItemBaseEntity.h" 11 | 12 | @implementation SMSectionListBaseEntity 13 | @synthesize unsortedArray = _unsortedArray, sections = _sections, items = _items; 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | - (void)sort 17 | { 18 | NSMutableArray* sections = [NSMutableArray array]; 19 | NSMutableArray* items = [NSMutableArray array]; 20 | NSMutableArray* aItems = nil; 21 | #ifdef DEBUG 22 | NSLog(@"================before===================="); 23 | for (SMSectionItemBaseEntity* e in self.unsortedArray) { 24 | NSLog(@"%@", e.name); 25 | } 26 | #endif 27 | 28 | NSArray* sortedArray = [self.unsortedArray sortedArrayUsingSelector:@selector(compare:)]; 29 | 30 | #ifdef DEBUG 31 | NSLog(@"=================after sort====================="); 32 | 33 | for (SMSectionItemBaseEntity* e in sortedArray) { 34 | NSLog(@"%@", e.name); 35 | } 36 | #endif 37 | // step1、初始生成26 + 1个sections和items 38 | // step2、根据每个话题首字母,插入对应的数组aItems中 39 | // step3、删除没有元素的数组aItems和section 40 | 41 | // step1 42 | for (unichar c = 'A'; c <= 'Z'; c++) { 43 | [sections addObject:[NSString stringWithFormat:@"%c", c]]; 44 | [items addObject:[NSMutableArray array]]; 45 | } 46 | [sections addObject:@"#"]; 47 | [items addObject:[NSMutableArray array]]; 48 | 49 | // step2 50 | int index = 0; 51 | for (SMSectionItemBaseEntity* e in sortedArray) { 52 | if (e.firstLetter >= 'A' && e.firstLetter <= 'Z') { 53 | index = e.firstLetter - 'A'; 54 | aItems = [items objectAtIndex:index]; 55 | [aItems addObject:e]; 56 | } 57 | else { 58 | aItems = [items objectAtIndex:items.count - 1]; 59 | [aItems addObject:e]; 60 | } 61 | } 62 | 63 | // step3 64 | NSMutableArray* newSections = [NSMutableArray array]; 65 | NSMutableArray* newItems = [NSMutableArray array]; 66 | aItems = nil; 67 | for (int i = 0; i < items.count; i++) { 68 | aItems = [items objectAtIndex:i]; 69 | if (aItems.count > 0) { 70 | [newSections addObject:[sections objectAtIndex:i]]; 71 | [newItems addObject:aItems]; 72 | } 73 | } 74 | 75 | self.sections = newSections; 76 | self.items = newItems; 77 | 78 | #ifdef DEBUG 79 | NSLog(@"=================after section==============="); 80 | for (NSArray* array in self.items) { 81 | NSLog(@"________________________________________"); 82 | for (SMSectionItemBaseEntity* e in array) { 83 | NSLog(@"%@", e.name); 84 | } 85 | } 86 | NSLog(@"=================end======================"); 87 | #endif 88 | } 89 | @end 90 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMStatusEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMWeiboMainbodyEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-1-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLNimbusEntity.h" 11 | #import "SMUserInfoEntity.h" 12 | 13 | @interface SMKeywordEntity : NSObject 14 | @property (nonatomic, copy) NSString* keyword; 15 | @property (nonatomic, assign) NSRange range; 16 | @end 17 | @interface SMStatusEntity : JLNimbusEntity 18 | 19 | @property (nonatomic, strong) SMUserInfoEntity *user; 20 | @property (nonatomic, strong) SMStatusEntity *retweeted_status; 21 | @property (nonatomic, copy) NSString *created_at; 22 | @property (nonatomic, copy) NSString *blogID; 23 | @property (nonatomic, copy) NSString *blogMID; 24 | @property (nonatomic, copy) NSString *blogIDStr; 25 | @property (nonatomic, copy) NSString *text; 26 | @property (nonatomic, copy) NSString *source; 27 | @property (nonatomic, strong) NSDate *timestamp; 28 | 29 | @property (assign) BOOL favorited; 30 | @property (assign) BOOL truncated; 31 | 32 | @property (nonatomic, copy) NSString *thumbnail_pic; 33 | @property (nonatomic, copy) NSString *bmiddle_pic; 34 | @property (nonatomic, copy) NSString *original_pic; 35 | 36 | @property (assign) int reposts_count; 37 | @property (assign) int comments_count; 38 | @property (assign) int attitudes_count; 39 | 40 | @property (nonatomic, strong) NSArray* atPersonRanges; 41 | @property (nonatomic, strong) NSArray* sharpTrendRanges; 42 | @property (nonatomic, strong) NSArray* emotionRanges; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMStatusEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMWeiboMainbodyEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-1-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMStatusEntity.h" 10 | #import "SMJSONKeys.h" 11 | #import "NSString+StringValue.h" 12 | #import "NSDateAdditions.h" 13 | #import "SMRegularParser.h" 14 | 15 | @implementation SMKeywordEntity 16 | @end 17 | 18 | @implementation SMStatusEntity 19 | 20 | /////////////////////////////////////////////////////////////////////////////////////////////////// 21 | - (id)initWithDictionary:(NSDictionary*)dic 22 | { 23 | if (!dic.count || ![dic isKindOfClass:[NSDictionary class]]) { 24 | return nil; 25 | } 26 | 27 | self = [super initWithDictionary:dic]; 28 | if (self) { 29 | self.user = (SMUserInfoEntity *)[SMUserInfoEntity entityWithDictionary:dic[JSON_STATUS_USER]]; 30 | self.retweeted_status = (SMStatusEntity *)[SMStatusEntity entityWithDictionary:dic[JSON_STATUS_RETWEEDTED_STATUS]]; 31 | self.created_at = dic[JSON_STATUS_CREATED_AT]; 32 | self.blogID = [NSString getStringValue:dic[JSON_STATUS_ID]]; 33 | self.blogMID = [NSString getStringValue:dic[JSON_STATUS_MID]]; 34 | self.blogIDStr = dic[JSON_STATUS_IDSTR]; 35 | self.text = dic[JSON_STATUS_TEXT]; 36 | self.source = [self getSourceString:dic[JSON_STATUS_SOURCE]]; 37 | self.favorited = [dic[JSON_STATUS_FAVORITED] boolValue]; 38 | self.truncated = [dic[JSON_STATUS_TRUNCATED] boolValue]; 39 | self.thumbnail_pic = dic[JSON_STATUS_THUMBNAIL_PIC]; 40 | self.bmiddle_pic = dic[JSON_STATUS_BMIDDLE_PIC]; 41 | self.original_pic = dic[JSON_STATUS_ORIGINAL_PIC]; 42 | self.reposts_count = [dic[JSON_STATUS_REPOSTS_COUNT] intValue]; 43 | self.comments_count = [dic[JSON_STATUS_COMMENTS_COUNT] intValue]; 44 | self.attitudes_count = [dic[JSON_STATUS_ATTITUDES_COUNT] intValue]; 45 | self.timestamp = [NSDate formatDateFromString:self.created_at]; 46 | 47 | // 与其每个微博加载都卡,不如这边一次都解析好 48 | [self parseAllKeywords]; 49 | } 50 | return self; 51 | } 52 | 53 | /////////////////////////////////////////////////////////////////////////////////////////////////// 54 | +(JLNimbusEntity *) entityWithDictionary:(NSDictionary *)dic { 55 | if (!dic.count || ![dic isKindOfClass:[NSDictionary class]]) { 56 | return nil; 57 | } 58 | 59 | SMStatusEntity *entity = [[SMStatusEntity alloc] initWithDictionary:dic]; 60 | return entity; 61 | } 62 | 63 | /////////////////////////////////////////////////////////////////////////////////////////////////// 64 | //谈微博 65 | - (NSString*)getSourceString:(NSString*)htmlSource 66 | { 67 | NSRange range1 = [htmlSource rangeOfString:@"\">"]; 68 | NSRange range2 = [htmlSource rangeOfString:@"/a>"]; 69 | NSRange sourceRange = NSMakeRange(range1.location + range1.length, 70 | range2.location - (range1.location + range1.length) - 1); 71 | NSString* source = [htmlSource substringWithRange:sourceRange]; 72 | return [NSString stringWithFormat:@"来自%@", source]; 73 | } 74 | 75 | /////////////////////////////////////////////////////////////////////////////////////////////////// 76 | // 识别出 表情 at某人 share话题 标签 77 | - (void)parseAllKeywords 78 | { 79 | if (self.text.length) { 80 | // TODO: emotion 81 | // 考虑优先剔除表情,这样@和#不会勿标识 82 | if (!self.atPersonRanges) { 83 | self.atPersonRanges = [SMRegularParser keywordRangesOfAtPersonInString:self.text]; 84 | } 85 | if (!self.sharpTrendRanges) { 86 | self.sharpTrendRanges = [SMRegularParser keywordRangesOfSharpTrendInString:self.text]; 87 | } 88 | } 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMTrendEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendE.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-11. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionItemBaseEntity.h" 10 | 11 | @interface SMTrendEntity : SMSectionItemBaseEntity 12 | { 13 | 14 | } 15 | + (id)entityWithDictionary:(NSDictionary*)dic; 16 | - (NSString* )getNameWithSharp; 17 | @end 18 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMTrendEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendE.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-11. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMTrendEntity.h" 10 | #import "pinyin.h" 11 | 12 | @implementation SMTrendEntity 13 | 14 | /////////////////////////////////////////////////////////////////////////////////////////////////// 15 | /////////////////////////////////////////////////////////////////////////////////////////////////// 16 | #pragma mark Public 17 | 18 | /////////////////////////////////////////////////////////////////////////////////////////////////// 19 | + (id)entityWithDictionary:(NSDictionary*)dic 20 | { 21 | SMTrendEntity* entity = [SMTrendEntity new]; 22 | entity.name = [dic objectForKey:@"name"]; 23 | // TODO: 生成sortString 24 | if (entity.name.length > 0) { 25 | entity.sortString = [entity createSortString]; 26 | NSLog(@"%@ ---> %@", entity.name, entity.sortString); 27 | return entity; 28 | } 29 | else return nil; 30 | } 31 | 32 | /////////////////////////////////////////////////////////////////////////////////////////////////// 33 | - (NSString* )getNameWithSharp 34 | { 35 | return [NSString stringWithFormat:@"#%@#", self.name]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMTrendListEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendsEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMSectionListBaseEntity.h" 10 | 11 | @interface SMTrendListEntity : SMSectionListBaseEntity 12 | 13 | @property (nonatomic, copy) NSString* time; 14 | + (id)entityWithDictionary:(NSDictionary*)dic; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMTrendListEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendsEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-8. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMTrendListEntity.h" 10 | #import "SMTrendEntity.h" 11 | #import "pinyin.h" 12 | 13 | @implementation SMTrendListEntity 14 | //{ 15 | // "as_of" = 1385257540; 16 | // trends = { 17 | // "2013-11-24 09:45" = ( 18 | // { 19 | // amount = 30213; 20 | // delta = 30213; 21 | // name = "\U90ed\U4e66\U7476"; 22 | // query = "\U90ed\U4e66\U7476"; 23 | // }, 24 | // { 25 | // amount = 27045; 26 | // delta = 27045; 27 | // name = "\U91d1\U9a6c\U5956"; 28 | // query = "\U91d1\U9a6c\U5956"; 29 | // }) 30 | // } 31 | //} 32 | /////////////////////////////////////////////////////////////////////////////////////////////////// 33 | + (id)entityWithDictionary:(NSDictionary*)dic 34 | { 35 | SMTrendListEntity* entity = [SMTrendListEntity new]; 36 | NSDictionary* sourceDic = [dic objectForKey:JSON_TREND_LIST]; 37 | NSArray* keys = [sourceDic allKeys]; 38 | if (keys.count > 0) { 39 | NSString* key = [keys objectAtIndex:0]; 40 | entity.time = key; 41 | NSArray* sourceArray = [sourceDic objectForKey:key]; 42 | entity.unsortedArray = [NSMutableArray arrayWithCapacity:sourceArray.count]; 43 | for (NSDictionary* d in sourceArray) { 44 | SMTrendEntity* aTrend = [SMTrendEntity entityWithDictionary:d]; 45 | if (aTrend) { 46 | [entity.unsortedArray addObject:aTrend]; 47 | } 48 | } 49 | 50 | [entity sort]; 51 | } 52 | return entity; 53 | } 54 | 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMUserInfoEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoEntity.h 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-2-22. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusEntity.h" 10 | #import "SMUserInfoEntity.h" 11 | 12 | @class SMStatusEntity; 13 | @interface SMUserInfoEntity : JLNimbusEntity 14 | 15 | @property(nonatomic, retain) SMStatusEntity *status; 16 | @property(nonatomic, copy) NSString *userID; 17 | @property(nonatomic, copy) NSString *screenName; 18 | @property(nonatomic, copy) NSString *name; 19 | @property(nonatomic, copy) NSString *profileImageUrl; 20 | @end 21 | -------------------------------------------------------------------------------- /SinaMBlog/Entities/SMUserInfoEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoEntity.m 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-2-22. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMUserInfoEntity.h" 10 | #import "SMJSONKeys.h" 11 | #import "NSString+StringValue.h" 12 | #import "SMStatusEntity.h" 13 | 14 | @implementation SMUserInfoEntity 15 | 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | - (id)initWithDictionary:(NSDictionary*)dic 18 | { 19 | self = [super initWithDictionary:dic]; 20 | if (self) { 21 | self.status = (SMStatusEntity *)[SMStatusEntity entityWithDictionary:dic[JSON_STATUS]]; 22 | self.userID = [NSString getStringValue:dic[JSON_USERINFO_USERID]]; 23 | self.screenName = dic[JSON_USERINFO_SCREEN_NAME]; 24 | self.name = dic[JSON_USERINFO_NAME]; 25 | self.profileImageUrl = dic[JSON_USERINFO_PROFILE_IMAGE_URL]; 26 | } 27 | return self; 28 | } 29 | 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// 31 | + (JLNimbusEntity *)entityWithDictionary:(NSDictionary *)dic 32 | { 33 | SMUserInfoEntity *entity = [[SMUserInfoEntity alloc] initWithDictionary:dic]; 34 | return entity; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /SinaMBlog/Images/Screenshot/homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Screenshot/homepage.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Screenshot/postnewstatus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Screenshot/postnewstatus.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Screenshot/repost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Screenshot/repost.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/37x-Checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/37x-Checkmark.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/37x-Checkmark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/37x-Checkmark@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/ReadMe: -------------------------------------------------------------------------------- 1 | 声明: 2 | Sina文件夹下图片使用来自新浪微博旧版本客户端,版权归新浪所有! 3 | 如侵权需删除,请联系本人,谢谢! 4 | 5 | email:jimneylee@gmail.com 6 | 新浪微博:jimneylee -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/clearbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/clearbutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/clearbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/clearbutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_camerabutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_camerabutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_camerabutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_camerabutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_camerabutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_camerabutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_camerabutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_camerabutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_checkbox.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_checkbox@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_checkbox@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_checkbox_checked.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_checkbox_checked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_checkbox_checked@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_emoticonbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_emoticonbutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_emoticonbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_emoticonbutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_emoticonbutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_emoticonbutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_emoticonbutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_emoticonbutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_keyboardbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_keyboardbutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_keyboardbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_keyboardbutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_keyboardbutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_keyboardbutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_keyboardbutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_keyboardbutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_locatebutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_locatebutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_locatebutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_locatebutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_locatebutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_locatebutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_locatebutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_locatebutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_mentionbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_mentionbutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_mentionbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_mentionbutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_mentionbutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_mentionbutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_mentionbutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_mentionbutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_placebutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_placebutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_placebutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_placebutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_trendbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_trendbutton_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_trendbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_trendbutton_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_trendbutton_background_highlighted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_trendbutton_background_highlighted.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/compose_trendbutton_background_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/compose_trendbutton_background_highlighted@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/emoticon_keyboard_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/emoticon_keyboard_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/emoticon_keyboard_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/emoticon_keyboard_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/Default-568h@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/Default.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/Default@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/icon.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/icon@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/icon_os7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/icon_os7.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/icon_default/icon_os7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/icon_default/icon_os7@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/navigationbar_button_delete_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/navigationbar_button_delete_background.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/navigationbar_button_delete_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/navigationbar_button_delete_background@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/preview_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/preview_button.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/preview_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/preview_button@2x.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/preview_save_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/preview_save_icon.png -------------------------------------------------------------------------------- /SinaMBlog/Images/Sina/preview_save_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/SinaMBlog/Images/Sina/preview_save_icon@2x.png -------------------------------------------------------------------------------- /SinaMBlog/JLSinaWeibo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | cn 7 | CFBundleDisplayName 8 | 开源新浪微博 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.sina.weibo.SNWeiboSDKDemo 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Editor 28 | CFBundleURLName 29 | com.weibo 30 | CFBundleURLSchemes 31 | 32 | wb2045436852 33 | 34 | 35 | 36 | CFBundleVersion 37 | 1.0 38 | LSApplicationQueriesSchemes 39 | 40 | sinaweibo 41 | 42 | LSRequiresIPhoneOS 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | 57 | UIViewControllerBasedStatusBarAppearance 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /SinaMBlog/JLSinaWeibo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SinaMBlogNimbus' target in the 'SinaMBlogNimbus' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | 15 | // self 16 | #import "SMGlobalConfig.h" 17 | #import "SMJSONKeys.h" 18 | #import "UIImage+nimbusImageNamed.h" 19 | 20 | // vendor 21 | #import "MBProgressHUD.h" 22 | #import "JLNimbusTimeline.h" 23 | #import "TTCategoryHeader.h" 24 | #import "WeiboSDK.h" 25 | 26 | // log switch 27 | #ifdef DEBUG 28 | # define NSLog(...) NSLog(__VA_ARGS__) 29 | #else 30 | # define NSLog(...) {} 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMAuthorizeModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMUserModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 11/26/13. 6 | // Copyright (c) 2013 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SMAuthorizeModel : NSObject 12 | 13 | + (void)sendAuthorizeRequest; 14 | + (BOOL)isAuthorized; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMAuthorizeModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMUserModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 11/26/13. 6 | // Copyright (c) 2013 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import "SMAuthorizeModel.h" 10 | 11 | @implementation SMAuthorizeModel 12 | 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | /////////////////////////////////////////////////////////////////////////////////////////////////// 15 | #pragma mark - Authorization 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | + (void)sendAuthorizeRequest 19 | { 20 | WBAuthorizeRequest *request = [WBAuthorizeRequest request]; 21 | request.redirectURI = SinaWeiboV2RedirectUri; 22 | request.scope = nil;//http://open.weibo.com/wiki/Scope 23 | request.userInfo = nil; 24 | [WeiboSDK sendRequest:request]; 25 | } 26 | 27 | /////////////////////////////////////////////////////////////////////////////////////////////////// 28 | // TODO:打算从这个类中剥离出来,放这里有点不合适 29 | /////////////////////////////////////////////////////////////////////////////////////////////////// 30 | + (BOOL)isAuthorized 31 | { 32 | return [SMGlobalConfig getCurrentLoginedUserId] 33 | && [SMGlobalConfig getCurrentLoginedAccessToken] 34 | && ![self isAuthorizeExpired]; 35 | } 36 | 37 | /////////////////////////////////////////////////////////////////////////////////////////////////// 38 | + (BOOL)isAuthorizeExpired 39 | { 40 | if ([SMGlobalConfig getCurrentLoginedExpiresIn]) { 41 | 42 | NSDate* expirationDate = [NSDate distantPast]; 43 | 44 | if ([SMGlobalConfig getCurrentLoginedExpiresIn]) { 45 | int expVal = [[SMGlobalConfig getCurrentLoginedExpiresIn] intValue]; 46 | if (expVal != 0) { 47 | expirationDate = [NSDate dateWithTimeIntervalSinceNow:expVal]; 48 | } 49 | } 50 | 51 | NSDate* now = [NSDate date]; 52 | return ([now compare:expirationDate] == NSOrderedDescending); 53 | } 54 | 55 | return NO; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMFriendsModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendsModel.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableModel.h" 10 | 11 | @interface SMFriendsModel : JLNimbusTableModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMFriendsModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMFriendsModel.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-12. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMFriendsModel.h" 10 | #import "SMAPIClient.h" 11 | #import "SMFriendEntity.h" 12 | #import "SMFriendListEntity.h" 13 | #import "SMFriendCell.h" 14 | 15 | @implementation SMFriendsModel 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | - (id)initWithDelegate:(id)delegate 19 | { 20 | self = [super initWithDelegate:delegate]; 21 | if (self) { 22 | 23 | } 24 | return self; 25 | } 26 | 27 | /////////////////////////////////////////////////////////////////////////////////////////////////// 28 | - (NSString*)relativePath 29 | { 30 | // 此接口为高级接口,还未申请http://open.weibo.com/wiki/2/friendships/groups 31 | return nil; 32 | } 33 | 34 | /////////////////////////////////////////////////////////////////////////////////////////////////// 35 | - (Class)objectClass 36 | { 37 | return [SMFriendEntity class]; 38 | } 39 | 40 | /////////////////////////////////////////////////////////////////////////////////////////////////// 41 | - (Class)cellClass 42 | { 43 | return [SMFriendCell class]; 44 | } 45 | 46 | /////////////////////////////////////////////////////////////////////////////////////////////////// 47 | - (void)loadDataWithBlock:(void(^)(NSArray* indexPaths, NSError *error))block more:(BOOL)more 48 | { 49 | NSString* relativePath = [self relativePath]; 50 | [[SMAPIClient sharedClient] GET:relativePath parameters:nil 51 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 52 | // remove all 53 | for (int i = 0; i < self.sections.count; i++) { 54 | [self removeSectionAtIndex:i]; 55 | } 56 | // reset with latest 57 | SMFriendListEntity* entity = [SMFriendListEntity entityWithDictionary:responseObject]; 58 | NITableViewModelSection* s = nil; 59 | NSMutableArray* modelSections = [NSMutableArray arrayWithCapacity:entity.items.count]; 60 | for (int i = 0; i < entity.items.count; i++) { 61 | s = [NITableViewModelSection section]; 62 | s.headerTitle = entity.sections[i]; 63 | s.rows = entity.items[i]; 64 | [modelSections addObject:s]; 65 | } 66 | self.sections = modelSections; 67 | self.sectionIndexTitles = entity.sections; 68 | 69 | if (block) { 70 | block(self.sections, nil); 71 | } 72 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 73 | NSLog(@"Error:%@", error.description); 74 | if (block) { 75 | block(nil, error); 76 | } 77 | }]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMMBlogPostModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPostModel.h 3 | // Zuoida 4 | // 5 | // Created by jimney lee on 12-9-20. 6 | // Copyright (c) 2012年 jimneylee. All rights reserved. 7 | // 8 | 9 | typedef enum { 10 | PostType_MBlogText, // 文字微博 11 | PostType_MBlogImage, // 图片微博 12 | PostType_Comment, // 评论微博 13 | PostType_Retweet, // 转发微博 14 | PostType_DraftMBlog, // 垃圾箱-文字/图片微博 15 | PostType_DraftComment, // 垃圾箱-评论微博 16 | PostType_DraftRetweet, // 垃圾箱-转发微博 17 | }PostType; 18 | 19 | @protocol ZDMBlogPostModelDelegate; 20 | @interface SMMBlogPostModel : NSObject { 21 | PostType _postType; 22 | } 23 | 24 | - (id)initWithDelegate:(id)delegate; 25 | 26 | @property (nonatomic, assign) id postDelegate; 27 | @property (nonatomic, retain) NSDictionary* parameters; 28 | @property (nonatomic, retain) UIImage* postImage; 29 | // 发送草稿箱的数据 30 | - (void)postDraftInfo:(NSDictionary*)info PostType:(PostType)type; 31 | 32 | // 普通发表微博、转发、评论 33 | - (void)postStatus:(NSString*)status latitude:(double)latitude longitude:(double)longitude; 34 | - (void)postImage:(UIImage*)image status:(NSString*)status latitude:(double)latitude longitude:(double)longitude; 35 | - (void)postComment:(NSString *)comment toBlogId:(NSString*)blogId; 36 | - (void)retweetStatus:(NSString *)status blogId:(NSString*)blogId isComment:(BOOL)isComment; 37 | 38 | // 草稿箱保存 39 | - (void)saveToDraftForPostStatus:(NSString *)status latitude:(double)latitude longitude:(double)longitude; 40 | - (void)saveToDraftForPostImage:(UIImage*)image status:(NSString *)status latitude:(double)latitude longitude:(double)longitude; 41 | - (void)saveToDraftForPostComment:(NSString *)comment toBlogId:(NSString*)blogId; 42 | - (void)saveToDraftForRetweetStatus:(NSString *)status blogId:(NSString*)blogId isComment:(BOOL)isComment; 43 | 44 | @end 45 | 46 | @protocol ZDMBlogPostModelDelegate 47 | 48 | - (void) postRequestFinished; 49 | - (void) postRequestFailed; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMMaxIdTimelineModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMMaxIdTimelineModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 7/27/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SMAPIClient.h" 11 | 12 | /////////////////////////////////////////////////////////////////////////////////////////////////// 13 | /////////////////////////////////////////////////////////////////////////////////////////////////// 14 | /////////////////////////////////////////////////////////////////////////////////////////////////// 15 | @interface SMMaxIdTimelineModel : JLNimbusTableModel 16 | 17 | @property (nonatomic, copy) NSString* oldMaxId; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMMaxIdTimelineModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMMaxIdTimelineModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 7/27/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMMaxIdTimelineModel.h" 10 | #import "NITableViewModel+Private.h" 11 | #import "NITableViewModel.h" 12 | #import "JLNimbusEntity.h" 13 | 14 | @interface SMMaxIdTimelineModel() 15 | @end 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | /////////////////////////////////////////////////////////////////////////////////////////////////// 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | @implementation SMMaxIdTimelineModel 21 | 22 | /////////////////////////////////////////////////////////////////////////////////////////////////// 23 | - (id)initWithDelegate:(id)delegate 24 | { 25 | self = [super initWithDelegate:delegate]; 26 | if (self) { 27 | } 28 | return self; 29 | } 30 | 31 | /////////////////////////////////////////////////////////////////////////////////////////////////// 32 | /////////////////////////////////////////////////////////////////////////////////////////////////// 33 | #pragma mark - Override 34 | 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// 36 | - (id)apiSharedClient 37 | { 38 | return [SMAPIClient sharedClient]; 39 | } 40 | 41 | /////////////////////////////////////////////////////////////////////////////////////////////////// 42 | - (void)loadDataWithBlock:(void(^)(NSArray* indexPaths, NSError *error))block 43 | more:(BOOL)more refresh:(BOOL)refresh 44 | { 45 | if (more) { 46 | self.oldMaxId = [NSString stringWithFormat:@"%lld", [self.oldMaxId longLongValue]-1]; 47 | } 48 | else { 49 | self.oldMaxId = @"0"; 50 | } 51 | [super loadDataWithBlock:(void(^)(NSArray* indexPaths, NSError *error))block more:more refresh:refresh]; 52 | } 53 | 54 | 55 | /////////////////////////////////////////////////////////////////////////////////////////////////// 56 | - (NSArray*)entitiesParsedFromListData:(NSArray*)listDataArray 57 | { 58 | // 设置当前maxId 59 | NSDictionary *dic = [listDataArray lastObject]; 60 | self.oldMaxId = [dic objectForKey:@"id"]; 61 | return [super entitiesParsedFromListData:listDataArray]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMMaxIdTimelineTypeModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMMaxIdTimelineModel.h" 10 | 11 | @interface SMMaxIdTimelineTypeModel : SMMaxIdTimelineModel 12 | 13 | - (id)initWithDelegate:(id)delegate timeLineType:(MBlogTimeLineType)type; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMMaxIdTimelineTypeModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMMaxIdTimelineTypeModel.h" 10 | #import "SMStatusEntity.h" 11 | #import "SMStatusCell.h" 12 | 13 | @interface SMMaxIdTimelineTypeModel() 14 | @property (nonatomic, assign) MBlogTimeLineType timelineType; 15 | @end 16 | 17 | @implementation SMMaxIdTimelineTypeModel 18 | 19 | /////////////////////////////////////////////////////////////////////////////////////////////////// 20 | - (id)initWithDelegate:(id)delegate 21 | { 22 | self = [super initWithDelegate:delegate]; 23 | if (self) { 24 | self.timelineType = MBlogTimeLineType_Friends; 25 | } 26 | return self; 27 | } 28 | 29 | /////////////////////////////////////////////////////////////////////////////////////////////////// 30 | - (id)initWithDelegate:(id)delegate timeLineType:(MBlogTimeLineType)type 31 | { 32 | self = [super initWithDelegate:delegate]; 33 | if (self) { 34 | self.timelineType = type; 35 | } 36 | return self; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (NSString*)relativePath 41 | { 42 | NSString* relativePath = nil; 43 | switch (_timelineType) { 44 | case MBlogTimeLineType_Friends: 45 | relativePath = [SMAPIClient relativePathForFriendsTimelineWithMaxId:self.oldMaxId]; 46 | break; 47 | 48 | case MBlogTimeLineType_User: 49 | relativePath = [SMAPIClient relativePathForUserTimelineWithUserID:nil maxId:self.oldMaxId]; 50 | break; 51 | 52 | case MBlogTimeLineType_AtMe: 53 | relativePath = [SMAPIClient relativePathForAtMeTimelineWithMaxId:self.oldMaxId]; 54 | break; 55 | 56 | default: 57 | break; 58 | } 59 | 60 | return relativePath; 61 | 62 | } 63 | 64 | /////////////////////////////////////////////////////////////////////////////////////////////////// 65 | - (NSString*)listKey 66 | { 67 | return JSON_STATUS_LIST; 68 | } 69 | 70 | /////////////////////////////////////////////////////////////////////////////////////////////////// 71 | - (Class)objectClass 72 | { 73 | return [SMStatusEntity class]; 74 | } 75 | 76 | /////////////////////////////////////////////////////////////////////////////////////////////////// 77 | - (Class)cellClass 78 | { 79 | return [SMStatusCell class]; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMPageTimelineModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableModel.h" 10 | 11 | @interface SMPageTimelineModel : JLNimbusTableModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMPageTimelineModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPageTimelineModel.h" 10 | #import "SMAPIClient.h" 11 | #import "SMStatusEntity.h" 12 | #import "SMStatusCell.h" 13 | 14 | @implementation SMPageTimelineModel 15 | 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | - (id)initWithDelegate:(id)delegate 18 | { 19 | self = [super initWithDelegate:delegate]; 20 | if (self) { 21 | 22 | } 23 | return self; 24 | } 25 | 26 | /////////////////////////////////////////////////////////////////////////////////////////////////// 27 | - (NSString*)relativePath 28 | { 29 | return [SMAPIClient relativePathForPublicTimelineWithPageIndex:self.pageIndex 30 | pageSize:self.pageSize]; 31 | } 32 | 33 | /////////////////////////////////////////////////////////////////////////////////////////////////// 34 | - (NSString*)listKey 35 | { 36 | return JSON_STATUS_LIST; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (Class)objectClass 41 | { 42 | return [SMStatusEntity class]; 43 | } 44 | 45 | /////////////////////////////////////////////////////////////////////////////////////////////////// 46 | - (Class)cellClass 47 | { 48 | return [SMStatusCell class]; 49 | } 50 | 51 | /////////////////////////////////////////////////////////////////////////////////////////////////// 52 | - (id)apiSharedClient 53 | { 54 | return [SMAPIClient sharedClient]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMTrendsModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "JLNimbusTableModel.h" 10 | 11 | @interface SMTrendsModel : JLNimbusTableModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMTrendsModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPublicTimelineModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMTrendsModel.h" 10 | #import "SMAPIClient.h" 11 | #import "SMTrendEntity.h" 12 | #import "SMTrendListEntity.h" 13 | #import "SMTrendCell.h" 14 | 15 | @implementation SMTrendsModel 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////////// 18 | - (id)initWithDelegate:(id)delegate 19 | { 20 | self = [super initWithDelegate:delegate]; 21 | if (self) { 22 | self.hasMoreData = NO; 23 | } 24 | return self; 25 | } 26 | 27 | /////////////////////////////////////////////////////////////////////////////////////////////////// 28 | - (NSString*)relativePath 29 | { 30 | return [SMAPIClient relativePathForWeeklyTrendsList]; 31 | } 32 | 33 | /////////////////////////////////////////////////////////////////////////////////////////////////// 34 | - (Class)objectClass 35 | { 36 | return [SMTrendEntity class]; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (Class)cellClass 41 | { 42 | return [SMTrendCell class]; 43 | } 44 | 45 | /////////////////////////////////////////////////////////////////////////////////////////////////// 46 | - (NSDictionary*)generateParameters 47 | { 48 | return nil; 49 | } 50 | 51 | /////////////////////////////////////////////////////////////////////////////////////////////////// 52 | - (void)loadDataWithBlock:(void(^)(NSArray* indexPaths, NSError *error))block more:(BOOL)more 53 | { 54 | NSString* relativePath = [self relativePath]; 55 | [[SMAPIClient sharedClient] GET:relativePath parameters:[self generateParameters] 56 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 57 | // remove all 58 | for (int i = 0; i < self.sections.count; i++) { 59 | [self removeSectionAtIndex:i]; 60 | } 61 | // reset with latest 62 | SMTrendListEntity* entity = [SMTrendListEntity entityWithDictionary:responseObject]; 63 | NITableViewModelSection* s = nil; 64 | NSMutableArray* modelSections = [NSMutableArray arrayWithCapacity:entity.items.count]; 65 | for (int i = 0; i < entity.items.count; i++) { 66 | s = [NITableViewModelSection section]; 67 | s.headerTitle = entity.sections[i]; 68 | s.rows = entity.items[i]; 69 | [modelSections addObject:s]; 70 | } 71 | self.sections = modelSections; 72 | self.sectionIndexTitles = entity.sections; 73 | 74 | if (block) { 75 | block(self.sections, nil); 76 | } 77 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 78 | NSLog(@"Error:%@", error.description); 79 | if (block) { 80 | block(nil, error); 81 | } 82 | }]; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMUserInfoModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMUserModel.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by ccjoy-jimneylee on 13-11-13. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SMUserInfoEntity; 12 | @interface SMUserInfoModel : NSObject 13 | 14 | @property(nonatomic, retain) SMUserInfoEntity *entity; 15 | 16 | - (void)loadUserInfoWithUserName:(NSString*)userName 17 | orUserId:(NSString*)userId 18 | block:(void(^)(SMUserInfoEntity* entity, NSError* error))block; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /SinaMBlog/Models/SMUserInfoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMUserModel.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by ccjoy-jimneylee on 13-11-13. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMUserInfoModel.h" 10 | #import "SMAPIClient.h" 11 | #import "SMUserInfoEntity.h" 12 | 13 | @implementation SMUserInfoModel 14 | 15 | ////////////////////////////////////////////////////////////////////////////////////////////////////// 16 | - (NSString*)relativePathWithUserName:(NSString*)userName orUserId:(NSString*)userId { 17 | return [SMAPIClient relativePathForUserInfoWithUserName:userName orUserId:userId]; 18 | } 19 | 20 | /////////////////////////////////////////////////////////////////////////////////////////////////// 21 | - (void)loadUserInfoWithUserName:(NSString*)userName 22 | orUserId:(NSString*)userId 23 | block:(void(^)(SMUserInfoEntity* entity, NSError* error))block 24 | { 25 | [[SMAPIClient sharedClient] GET:[self relativePathWithUserName:userName orUserId:userId] 26 | parameters:nil 27 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 28 | if ([responseObject isKindOfClass:[NSDictionary class]]) { 29 | NSDictionary* dic = (NSDictionary*)responseObject; 30 | self.entity = [SMUserInfoEntity entityWithDictionary:dic]; 31 | if (block) { 32 | block(self.entity, nil); 33 | return; 34 | } 35 | } 36 | if (block) { 37 | NSError* error = [[NSError alloc] init]; 38 | block(nil, error); 39 | return; 40 | } 41 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 42 | if (block) { 43 | block(nil, error); 44 | } 45 | }]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /SinaMBlog/SMGlobalConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // TVGlobalConfig.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define APP_NAME [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] 12 | #define APP_VERSION [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] 13 | 14 | //"error":"applications over the unaudited use restrictions!" 15 | //报错参考此处:http://open.weibo.com/qa/index.php?qa=159&qa_1=%E7%94%A8%E6%88%B7%E6%8E%88%E6%9D%83%E5%90%8E%E5%87%BA%E7%8E%B0applications-over-unaudited-restrictions%E9%94%99%E8%AF%AF%E6%80%8E%E4%B9%88%E8%A7%A3%E5%86%B3%EF%BC%9F 16 | //#error @"please set your sina app key" 17 | #define SinaWeiboV2AppKey @"2045436852" 18 | #define SinaWeiboV2RedirectUri @"http://www.sina.com" 19 | 20 | // baidu map key 21 | #define BaiduMapEngineKey @"8502D0F8B5F266104698378D6A9010C31F850B49" 22 | 23 | // iOS 系统版本 24 | #define IOS_IS_AT_LEAST_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) 25 | #define IOS_IS_AT_LEAST_7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 26 | 27 | // Cell布局相关 28 | #define CELL_PADDING_10 10 29 | #define CELL_PADDING_8 8 30 | #define CELL_PADDING_6 6 31 | #define CELL_PADDING_4 4 32 | #define CELL_PADDING_2 2 33 | 34 | // TableView 视图背景 35 | #define TABLE_VIEW_BG_COLOR RGBCOLOR(237, 234, 234) 36 | #define CELL_CONTENT_VIEW_BG_COLOR RGBCOLOR(247, 247, 247) 37 | #define CELL_RETWEET_CONTENT_VIEW_BG_COLOR RGBCOLOR(251, 251, 251) 38 | #define CELL_CONTENT_VIEW_BORDER_COLOR RGBCOLOR(234, 234, 234) 39 | 40 | // 微博时间线信息类型 41 | typedef enum { 42 | MBlogTimeLineType_Public, // 随便看看 43 | MBlogTimeLineType_Friends, // 当前登录用户及关注好友的微博 44 | MBlogTimeLineType_User, // 用户发布的微博 45 | MBlogTimeLineType_AtMe, // @当前登录用户的微博 46 | MBlogTimeLineType_Comments, // 返回最新N条评论列表(发送的和接收到的) 47 | MBlogTimeLineType_CommentsToMe, // 评论我的微博 48 | MBlogTimeLineType_CommentsByMe, // 我发出的评论 49 | MBlogTimeLinetype_DirectMsgs // 登录用户的私信列表 50 | }MBlogTimeLineType; 51 | 52 | // 微博发送类型 53 | typedef enum 54 | { 55 | MBlogPostType_AtUser, 56 | MBlogPostType_AboutTrend, 57 | MBlogPostType_Common 58 | }MBlogPostType; 59 | 60 | //微博搜索类型 61 | typedef enum 62 | { 63 | SearchType_Statuses, 64 | SearchType_Users, 65 | SearchType_Topics 66 | }SearchType; 67 | 68 | @interface SMGlobalConfig : NSObject 69 | 70 | /////////////////////////////////////////////////////////////////////////////////////////////////// 71 | // OAuth 72 | + (void)setCurrentLoginedUserName:(NSString*)userName; 73 | + (NSString *)getCurrentLoginedUserName; 74 | + (void)setCurrentLoginedUserId:(NSString*)userId; 75 | + (NSString *)getCurrentLoginedUserId; 76 | + (void)setCurrentLoginedAccessToken:(NSString*)accessToken; 77 | + (NSString *)getCurrentLoginedAccessToken; 78 | + (void)setCurrentLoginedExpiresIn:(NSString*)expiresIn; 79 | + (NSString *)getCurrentLoginedExpiresIn; 80 | 81 | /////////////////////////////////////////////////////////////////////////////////////////////////// 82 | // UI 83 | + (void)showHUDMessage:(NSString*)msg addedToView:(UIView*)view; 84 | + (UIBarButtonItem*)createRefreshBarButtonItemWithTarget:(id)target action:(SEL)action; 85 | + (UIBarButtonItem*)createPostBarButtonItemWithTarget:(id)target action:(SEL)action; 86 | + (UIBarButtonItem*)createBarButtonItemWithTitle:(NSString*)buttonTitle target:(id)target action:(SEL)action; 87 | + (UILabel*)getNavigationBarTitleViewWithTitle:(NSString*)title; 88 | 89 | // Emotion 90 | + (NSArray* )emotionsArray; 91 | + (NSString*)pathForEmotionCode:(NSString*)code; 92 | + (NSString*)pathForEmotionCodeForHtml:(NSString*)code; 93 | 94 | // 草稿箱数据 95 | + (NSArray*)getDraftArray; 96 | + (void)saveToDraft:(NSMutableDictionary*)dic; 97 | + (BOOL)removeDraftWithIndex:(int)index; 98 | + (NSDictionary*)convertNSDataToUIImageForDraft:(NSDictionary*)dic; 99 | + (NSDictionary*)convertUIImageToNSDataForDraft:(NSDictionary*)dic; 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /SinaMBlog/Util/SMNetworkSpy.h: -------------------------------------------------------------------------------- 1 | // 2 | // TLGlobalConfig.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney Lee on 7/25/12. 6 | // Copyright (c) 2012 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "Reachability.h" 10 | /** 11 | * 网络连接状态的侦听者 12 | * 负责侦听当前网络是否连接,识别当前连接方式:2G/3G/Wifi 13 | */ 14 | @interface SMNetworkSpy : NSObject 15 | { 16 | Reachability* _reachability; 17 | BOOL _isReachableViaWiFi; 18 | BOOL _isReachableViaWWAN; 19 | BOOL _isReachable; 20 | } 21 | 22 | + (id)sharedNetworkSpy; 23 | + (BOOL)checkNetworkConnected; 24 | 25 | @property (nonatomic, retain) Reachability* reachability; 26 | @property (nonatomic) BOOL isReachableViaWiFi; 27 | @property (nonatomic) BOOL isReachableViaWWAN; 28 | 29 | - (void)spyNetwork; 30 | @end 31 | -------------------------------------------------------------------------------- /SinaMBlog/Util/SMNetworkSpy.m: -------------------------------------------------------------------------------- 1 | // 2 | // TLGlobalConfig.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney Lee on 7/25/12. 6 | // Copyright (c) 2012 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMNetworkSpy.h" 10 | #include 11 | 12 | @implementation SMNetworkSpy 13 | @synthesize reachability = _reachability; 14 | @synthesize isReachableViaWiFi = _isReachableViaWiFi; 15 | @synthesize isReachableViaWWAN = _isReachableViaWWAN; 16 | 17 | static SMNetworkSpy* sharedNetworkSpy = nil; 18 | 19 | + (id)sharedNetworkSpy 20 | { 21 | if (!sharedNetworkSpy) { 22 | sharedNetworkSpy = [[SMNetworkSpy alloc] init]; 23 | } 24 | 25 | return sharedNetworkSpy; 26 | } 27 | 28 | + (BOOL)checkNetworkConnected 29 | { 30 | Reachability *reac = [Reachability reachabilityWithHostName:@"www.baidu.com"]; 31 | 32 | if (![reac isReachable]) { 33 | UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"网络未连接" 34 | message:@"请确认网络是否连接正常" 35 | delegate:nil 36 | cancelButtonTitle:@"确定" otherButtonTitles:nil]; 37 | [alertView show]; 38 | return NO; 39 | } 40 | 41 | return YES; 42 | } 43 | 44 | #pragma mark - 45 | #pragma mark Network 46 | 47 | - (id)init 48 | { 49 | self = [super init]; 50 | if (self) { 51 | [[NSNotificationCenter defaultCenter] addObserver:self 52 | selector:@selector(networkChanged:) 53 | name:kReachabilityChangedNotification 54 | object:nil]; 55 | } 56 | return self; 57 | } 58 | 59 | - (void) spyNetwork 60 | { 61 | if (!self.reachability) { 62 | self.reachability = [Reachability reachabilityWithHostName:@"www.baidu.com"]; 63 | 64 | _isReachableViaWiFi = [self.reachability isReachableViaWiFi]; 65 | _isReachableViaWWAN = [self.reachability isReachableViaWWAN]; 66 | _isReachable = [self.reachability isReachable]; 67 | 68 | [self.reachability startNotifier]; 69 | 70 | [self showAlertViewForNotReachable]; 71 | } 72 | } 73 | 74 | - (void)networkChanged:(NSNotification*)noti 75 | { 76 | Reachability* reac = (Reachability*)noti.object; 77 | 78 | _isReachableViaWiFi = [reac isReachableViaWiFi]; 79 | _isReachableViaWWAN = [reac isReachableViaWWAN]; 80 | _isReachable = [reac isReachable]; 81 | 82 | [self showCurrentReachableAlertView]; 83 | } 84 | 85 | #pragma mark - 86 | #pragma mark Public 87 | - (void)showAlertViewForNotReachable; 88 | { 89 | if (!_isReachable) { 90 | UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"网络未连接" 91 | message:@"请确认网络是否连接正常" 92 | delegate:nil 93 | cancelButtonTitle:@"确定" otherButtonTitles:nil]; 94 | [alertView show]; 95 | } 96 | } 97 | 98 | 99 | - (void)showCurrentReachableAlertView 100 | { 101 | NSString* title = @"网络未连接"; 102 | 103 | if (!_isReachable) { 104 | title = @"网络未连接"; 105 | } 106 | else if (_isReachableViaWiFi) { 107 | title = @"当前wifi已连接"; 108 | } 109 | else if (_isReachableViaWWAN) { 110 | title = @"当前2g/3g已连接"; 111 | } 112 | 113 | [SMGlobalConfig showHUDMessage:title addedToView:[UIApplication sharedApplication].keyWindow]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /SinaMBlog/Util/SMRegularParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMRegularParser.h 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-2-18. 6 | // Copyright (c) 2013年 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SMRegularParser : NSObject 12 | 13 | // 返回所有at某人的range数组 14 | + (NSArray *)keywordRangesOfAtPersonInString:(NSString *)string; 15 | 16 | // 返回所有#话题的range数组 17 | + (NSArray *)keywordRangesOfSharpTrendInString:(NSString *)string; 18 | 19 | // 返回表情的range数组 20 | + (NSArray *)keywordRangesOfEmotionInString:(NSString *)string; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /SinaMBlog/Util/SMRegularParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMRegularParser.m 3 | // SinaMBlog 4 | // 5 | // Created by Jiang Yu on 13-2-18. 6 | // Copyright (c) 2013年 SuperMaxDev. All rights reserved. 7 | // 8 | 9 | #import "SMRegularParser.h" 10 | #import "NSStringAdditions.h" 11 | #import "SMStatusEntity.h" 12 | 13 | static NSString *atRegular = @"@[^.,:;!?()\\s#@。,:;!?()]+"; 14 | static NSString *sharpRegular = @"#(.*?)#"; 15 | static NSString *iconRegular = @"\\[([\u4e00-\u9fa5]+)\\]"; 16 | 17 | @implementation SMRegularParser 18 | 19 | + (NSArray *)keywordRangesOfAtPersonInString:(NSString *)string { 20 | NSError *error; 21 | 22 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:atRegular 23 | options:NSRegularExpressionCaseInsensitive 24 | error:&error]; 25 | __block NSMutableArray *rangesArray = [NSMutableArray array]; 26 | __block NSString* keyword = nil; 27 | __block SMKeywordEntity* keywordEntity = nil; 28 | [regex enumerateMatchesInString:string 29 | options:0 30 | range:NSMakeRange(0, string.length) 31 | usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 32 | NSRange resultRange = [result range]; 33 | // range & name 34 | keyword = [regex replacementStringForResult:result 35 | inString:string 36 | offset:0 37 | template:@"$0"]; 38 | if (keyword.length) { 39 | // @someone 40 | keyword = [keyword substringWithRange:NSMakeRange(1, keyword.length-1)]; 41 | keywordEntity = [[SMKeywordEntity alloc] init]; 42 | keywordEntity.keyword = keyword; 43 | keywordEntity.range = resultRange; 44 | [rangesArray addObject:keywordEntity]; 45 | } 46 | }]; 47 | return rangesArray; 48 | } 49 | 50 | + (NSArray *)keywordRangesOfSharpTrendInString:(NSString *)string { 51 | NSError *error; 52 | 53 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:sharpRegular 54 | options:NSRegularExpressionCaseInsensitive 55 | error:&error]; 56 | __block NSMutableArray *rangesArray = [NSMutableArray array]; 57 | __block NSString* keyword = nil; 58 | __block SMKeywordEntity* keywordEntity = nil; 59 | [regex enumerateMatchesInString:string 60 | options:0 61 | range:NSMakeRange(0, string.length) 62 | usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 63 | NSRange resultRange = [result range]; 64 | // range & trend 65 | keyword = [regex replacementStringForResult:result 66 | inString:string 67 | offset:0 68 | template:@"$0"]; 69 | if (keyword.length) { 70 | // #sometrend# 71 | keyword = [keyword substringWithRange:NSMakeRange(1, keyword.length-2)]; 72 | keywordEntity = [[SMKeywordEntity alloc] init]; 73 | keywordEntity.keyword = keyword; 74 | keywordEntity.range = resultRange; 75 | [rangesArray addObject:keywordEntity]; 76 | } 77 | }]; 78 | return rangesArray; 79 | } 80 | 81 | + (NSArray *)keywordRangesOfEmotionInString:(NSString *)string { 82 | NSError *error; 83 | 84 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:iconRegular 85 | options:NSRegularExpressionCaseInsensitive 86 | error:&error]; 87 | __block NSMutableArray *rangesArray = [NSMutableArray array]; 88 | __block NSMutableString *mutableString = [string mutableCopy]; 89 | __block NSInteger offset = 0; 90 | __block NSString* keyword = nil; 91 | __block SMKeywordEntity* keywordEntity = nil; 92 | [regex enumerateMatchesInString:string 93 | options:0 94 | range:NSMakeRange(0, string.length) 95 | usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 96 | NSRange resultRange = [result range]; 97 | resultRange.location += offset; 98 | // range & emotion 99 | keyword = [regex replacementStringForResult:result 100 | inString:mutableString 101 | offset:offset 102 | template:@"$0"]; 103 | keywordEntity = [[SMKeywordEntity alloc] init]; 104 | keywordEntity.keyword = keyword; 105 | keywordEntity.range = resultRange; 106 | [rangesArray addObject:keywordEntity]; 107 | 108 | [mutableString replaceCharactersInRange:resultRange withString:@""]; 109 | offset -= resultRange.length; 110 | }]; 111 | // 考虑去掉表情标签的字串如何返回 112 | return rangesArray; 113 | } 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMFriendCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendCell.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-8-15. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "NICellCatalog.h" 10 | 11 | @interface SMFriendCell : NITextCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMFriendCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendCell.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-8-15. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMFriendCell.h" 10 | #import "SMFriendEntity.h" 11 | 12 | #define TITLE_FONT_SIZE [UIFont boldSystemFontOfSize:17.f] 13 | 14 | @implementation SMFriendCell 15 | 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | + (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView 18 | { 19 | return 44.0f; 20 | } 21 | 22 | /////////////////////////////////////////////////////////////////////////////////////////////////// 23 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 24 | { 25 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 26 | if (self) { 27 | self.selectionStyle = UITableViewCellSelectionStyleBlue; 28 | self.textLabel.font = TITLE_FONT_SIZE; 29 | 30 | } 31 | return self; 32 | } 33 | 34 | 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// 36 | - (void)prepareForReuse 37 | { 38 | [super prepareForReuse]; 39 | } 40 | 41 | /////////////////////////////////////////////////////////////////////////////////////////////////// 42 | - (void)layoutSubviews 43 | { 44 | [super layoutSubviews]; 45 | } 46 | 47 | /////////////////////////////////////////////////////////////////////////////////////////////////// 48 | - (BOOL)shouldUpdateCellWithObject:(id)object 49 | { 50 | [super shouldUpdateCellWithObject:object]; 51 | if ([object isKindOfClass:[SMFriendEntity class]]) { 52 | SMFriendEntity* entity = (SMFriendEntity*)object; 53 | self.textLabel.text = [entity getNameWithAt]; 54 | } 55 | return YES; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMFullScreenPhotoBrowseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMFullScreenPhotoBrowseC.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by ccjoy-jimneylee on 14-1-6. 6 | // Copyright (c) 2014年 SuperMaxDev. All rights reserved. 7 | // 8 | #import "UIImageView+WebCache.h" 9 | @interface SMFullScreenPhotoBrowseView : UIView 10 | 11 | @property (nonatomic, copy) NSString* urlPath; 12 | @property (nonatomic, strong) UIImage* thumbnail; 13 | @property (nonatomic, strong) UIScrollView* scrollView; 14 | @property (nonatomic, strong) UIImageView* imageView; 15 | 16 | - (id)initWithUrlPath:(NSString *)urlPath thumbnail:(UIImage*)thumbnail fromRect:(CGRect)rect; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMPostButtonBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMPostButtonBar.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "TTButtonBar.h" 10 | @interface SMPostButtonBar : TTButtonBar 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMPostButtonBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMPostButtonBar.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 13-3-5. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMPostButtonBar.h" 10 | 11 | @implementation SMPostButtonBar 12 | 13 | - (id)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | self.backgroundColor = [UIColor whiteColor]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)layoutSubviews 23 | { 24 | CGFloat kWidth = 26.f; 25 | CGFloat kTopSpace = (self.height - kWidth) * .5f; 26 | CGFloat kSpace = (self.width - ( kWidth * _buttons.count)) / (_buttons.count + 1); 27 | 28 | // 限制间隔距离,最大33.3,按照一排5个布局标准 29 | // 33.3 = (320 - 24 * 5)/ (5+1) 30 | CGFloat kNormalMaxCount = 5; 31 | CGFloat kMaxSpace = (self.width - kWidth * kNormalMaxCount) / (kNormalMaxCount + 1); 32 | if (kSpace > kMaxSpace) { 33 | kSpace = kMaxSpace; 34 | } 35 | CGFloat left = kSpace; 36 | for (UIButton* button in _buttons) { 37 | button.frame = CGRectMake(left, kTopSpace, kWidth, kWidth); 38 | left = button.right + kSpace; 39 | } 40 | } 41 | @end 42 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMStatusCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMStatusCell.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by Lee jimney on 10/30/13. 6 | // Copyright (c) 2013 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "NICellCatalog.h" 10 | 11 | @interface SMStatusCell : NITextCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMTrendCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendCell.h 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-8-15. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "NICellCatalog.h" 10 | 11 | @interface SMTrendCell : NITextCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /SinaMBlog/Views/SMTrendCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SMTrendCell.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-8-15. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "SMTrendCell.h" 10 | #import "SMTrendEntity.h" 11 | 12 | #define TITLE_FONT_SIZE [UIFont boldSystemFontOfSize:17.f] 13 | 14 | @implementation SMTrendCell 15 | 16 | /////////////////////////////////////////////////////////////////////////////////////////////////// 17 | + (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView 18 | { 19 | return 44.0f; 20 | } 21 | 22 | /////////////////////////////////////////////////////////////////////////////////////////////////// 23 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 24 | { 25 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 26 | if (self) { 27 | self.selectionStyle = UITableViewCellSelectionStyleBlue; 28 | self.textLabel.font = TITLE_FONT_SIZE; 29 | 30 | } 31 | return self; 32 | } 33 | 34 | 35 | /////////////////////////////////////////////////////////////////////////////////////////////////// 36 | - (void)prepareForReuse 37 | { 38 | [super prepareForReuse]; 39 | } 40 | 41 | /////////////////////////////////////////////////////////////////////////////////////////////////// 42 | - (void)layoutSubviews 43 | { 44 | [super layoutSubviews]; 45 | } 46 | 47 | /////////////////////////////////////////////////////////////////////////////////////////////////// 48 | - (BOOL)shouldUpdateCellWithObject:(id)object 49 | { 50 | [super shouldUpdateCellWithObject:object]; 51 | if ([object isKindOfClass:[SMTrendEntity class]]) { 52 | SMTrendEntity* entity = (SMTrendEntity*)object; 53 | self.textLabel.text = [entity getNameWithSharp]; 54 | } 55 | return YES; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /SinaMBlog/Views/TTButtonBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2009-2011 Facebook 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | /** 18 | * A box containing buttons with a consistent style. 19 | */ 20 | @interface TTButtonBar : UIView { 21 | NSMutableArray* _buttons; 22 | NSString* _buttonStyle; 23 | } 24 | 25 | @property (nonatomic, copy) NSArray* buttons; 26 | @property (nonatomic, copy) NSString* buttonStyle; 27 | 28 | - (void)addButton:(NSString*)title target:(id)target action:(SEL)selector; 29 | - (void)removeButtons; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /SinaMBlog/Views/TTButtonBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2009-2011 Facebook 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #import "TTButtonBar.h" 18 | 19 | // UI 20 | #import "UIViewAdditions.h" 21 | 22 | // Core 23 | #import "TTCorePreprocessorMacros.h" 24 | 25 | static CGFloat kPadding = 10.0f; 26 | static CGFloat kButtonHeight = 30.0f; 27 | static CGFloat kButtonMaxWidth = 120.0f; 28 | 29 | 30 | /////////////////////////////////////////////////////////////////////////////////////////////////// 31 | /////////////////////////////////////////////////////////////////////////////////////////////////// 32 | /////////////////////////////////////////////////////////////////////////////////////////////////// 33 | @implementation TTButtonBar 34 | 35 | @synthesize buttons = _buttons; 36 | @synthesize buttonStyle = _buttonStyle; 37 | 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (id)initWithFrame:(CGRect)frame { 41 | self = [super initWithFrame:frame]; 42 | if (self) { 43 | _buttons = [[NSMutableArray alloc] init]; 44 | 45 | self.buttonStyle = @"toolbarButton:"; 46 | } 47 | return self; 48 | } 49 | 50 | 51 | /////////////////////////////////////////////////////////////////////////////////////////////////// 52 | /////////////////////////////////////////////////////////////////////////////////////////////////// 53 | #pragma mark - 54 | #pragma mark UIResponder 55 | 56 | 57 | /////////////////////////////////////////////////////////////////////////////////////////////////// 58 | - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event { 59 | // XXXjoe Hackish? This prevents weird things from happening when the user touches the 60 | // background of the button bar while it is used as the menu in a table view. 61 | } 62 | 63 | 64 | /////////////////////////////////////////////////////////////////////////////////////////////////// 65 | /////////////////////////////////////////////////////////////////////////////////////////////////// 66 | #pragma mark - 67 | #pragma mark UIView 68 | 69 | 70 | /////////////////////////////////////////////////////////////////////////////////////////////////// 71 | - (void)layoutSubviews { 72 | CGFloat buttonWidth = floor((self.width-kPadding) / _buttons.count)-kPadding; 73 | if (buttonWidth > kButtonMaxWidth) { 74 | buttonWidth = kButtonMaxWidth; 75 | } 76 | 77 | CGFloat x = kPadding + floor(self.width/2 - ((buttonWidth+kPadding)*_buttons.count)/2); 78 | CGFloat y = floor(self.height/2 - kButtonHeight/2); 79 | 80 | for (UIButton* button in _buttons) { 81 | button.frame = CGRectMake(x, y, buttonWidth, kButtonHeight); 82 | x += button.width + kPadding; 83 | } 84 | } 85 | 86 | 87 | /////////////////////////////////////////////////////////////////////////////////////////////////// 88 | /////////////////////////////////////////////////////////////////////////////////////////////////// 89 | #pragma mark - 90 | #pragma mark Public 91 | 92 | 93 | /////////////////////////////////////////////////////////////////////////////////////////////////// 94 | - (void)addButton:(NSString*)title target:(id)target action:(SEL)selector { 95 | UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom]; 96 | [button setTitle:title forState:UIControlStateNormal]; 97 | [button addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside]; 98 | [self addSubview:button]; 99 | [_buttons addObject:button]; 100 | } 101 | 102 | 103 | /////////////////////////////////////////////////////////////////////////////////////////////////// 104 | - (void)removeButtons { 105 | for (UIButton* button in _buttons) { 106 | [button removeFromSuperview]; 107 | } 108 | [_buttons removeAllObjects]; 109 | } 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /SinaMBlog/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /SinaMBlog/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SinaMBlogNimbus 4 | // 5 | // Created by jimneylee on 13-10-30. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | 修改为开源新浪微博,新浪开发平台已被申请,后面想办法联系到申请的人。 3 | OpenSinaMBlog 4 | 5 | TODO: 6 | 1、表情解析 7 | 其他功能由于新浪接口原因,不在继续,基本框架已好,其他新接口添加应该难度不大 -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Blurring.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Blurring.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Blurring) 15 | 16 | -(UIImage*)gaussianBlurWithBias:(NSInteger)bias; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Blurring.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Blurring.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Blurring.h" 12 | #import 13 | 14 | 15 | static int16_t __s_gaussianblur_kernel_5x5[25] = { 16 | 1, 4, 6, 4, 1, 17 | 4, 16, 24, 16, 4, 18 | 6, 24, 36, 24, 6, 19 | 4, 16, 24, 16, 4, 20 | 1, 4, 6, 4, 1 21 | }; 22 | 23 | 24 | @implementation UIImage (NYX_Blurring) 25 | 26 | -(UIImage*)gaussianBlurWithBias:(NSInteger)bias 27 | { 28 | /// Create an ARGB bitmap context 29 | const size_t width = (size_t)self.size.width; 30 | const size_t height = (size_t)self.size.height; 31 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 32 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow); 33 | if (!bmContext) 34 | return nil; 35 | 36 | /// Draw the image in the bitmap context 37 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 38 | 39 | /// Grab the image raw data 40 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 41 | if (!data) 42 | { 43 | CGContextRelease(bmContext); 44 | return nil; 45 | } 46 | 47 | const size_t n = sizeof(UInt8) * width * height * 4; 48 | void* outt = malloc(n); 49 | vImage_Buffer src = {data, height, width, bytesPerRow}; 50 | vImage_Buffer dest = {outt, height, width, bytesPerRow}; 51 | vImageConvolveWithBias_ARGB8888(&src, &dest, NULL, 0, 0, __s_gaussianblur_kernel_5x5, 5, 5, 256/*divisor*/, bias, NULL, kvImageCopyInPlace); 52 | memcpy(data, outt, n); 53 | free(outt); 54 | 55 | CGImageRef blurredImageRef = CGBitmapContextCreateImage(bmContext); 56 | UIImage* blurred = [UIImage imageWithCGImage:blurredImageRef]; 57 | 58 | /// Cleanup 59 | CGImageRelease(blurredImageRef); 60 | CGContextRelease(bmContext); 61 | 62 | return blurred; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Enhancing.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Enhancing.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/12/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | @interface UIImage (NYX_Enhancing) 12 | 13 | -(UIImage*)autoEnhance; 14 | 15 | -(UIImage*)redEyeCorrection; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Enhancing.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Enhancing.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 03/12/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Enhancing.h" 12 | #import 13 | 14 | 15 | @implementation UIImage (NYX_Enhancing) 16 | 17 | -(UIImage*)autoEnhance 18 | { 19 | /// No Core Image, return original image 20 | if (![CIImage class]) 21 | return self; 22 | 23 | CIImage* ciImage = [[CIImage alloc] initWithCGImage:self.CGImage]; 24 | 25 | NSArray* adjustments = [ciImage autoAdjustmentFiltersWithOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:kCIImageAutoAdjustRedEye]]; 26 | 27 | for (CIFilter* filter in adjustments) 28 | { 29 | [filter setValue:ciImage forKey:kCIInputImageKey]; 30 | ciImage = filter.outputImage; 31 | } 32 | 33 | CIContext* ctx = [CIContext contextWithOptions:nil]; 34 | CGImageRef cgImage = [ctx createCGImage:ciImage fromRect:[ciImage extent]]; 35 | UIImage* final = [UIImage imageWithCGImage:cgImage]; 36 | CGImageRelease(cgImage); 37 | return final; 38 | } 39 | 40 | -(UIImage*)redEyeCorrection 41 | { 42 | /// No Core Image, return original image 43 | if (![CIImage class]) 44 | return self; 45 | 46 | CIImage* ciImage = [[CIImage alloc] initWithCGImage:self.CGImage]; 47 | 48 | /// Get the filters and apply them to the image 49 | NSArray* filters = [ciImage autoAdjustmentFiltersWithOptions:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:kCIImageAutoAdjustEnhance]]; 50 | for (CIFilter* filter in filters) 51 | { 52 | [filter setValue:ciImage forKey:kCIInputImageKey]; 53 | ciImage = filter.outputImage; 54 | } 55 | 56 | /// Create the corrected image 57 | CIContext* ctx = [CIContext contextWithOptions:nil]; 58 | CGImageRef cgImage = [ctx createCGImage:ciImage fromRect:[ciImage extent]]; 59 | UIImage* final = [UIImage imageWithCGImage:cgImage]; 60 | CGImageRelease(cgImage); 61 | return final; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Filtering.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Filters.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Filtering) 15 | 16 | -(UIImage*)brightenWithValue:(float)factor; 17 | 18 | -(UIImage*)contrastAdjustmentWithValue:(float)value; 19 | 20 | -(UIImage*)edgeDetectionWithBias:(NSInteger)bias; 21 | 22 | -(UIImage*)embossWithBias:(NSInteger)bias; 23 | 24 | -(UIImage*)gammaCorrectionWithValue:(float)value; 25 | 26 | -(UIImage*)grayscale; 27 | 28 | -(UIImage*)invert; 29 | 30 | -(UIImage*)opacity:(float)value; 31 | 32 | -(UIImage*)sepia; 33 | 34 | -(UIImage*)sharpenWithBias:(NSInteger)bias; 35 | 36 | -(UIImage*)unsharpenWithBias:(NSInteger)bias; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Masking.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Masking.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Masking) 15 | 16 | -(UIImage*)maskWithImage:(UIImage*)mask; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Masking.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Masking.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/06/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Masking.h" 12 | 13 | 14 | @implementation UIImage (NYX_Masking) 15 | 16 | -(UIImage*)maskWithImage:(UIImage*)maskImage 17 | { 18 | /// Create a bitmap context with valid alpha 19 | const size_t originalWidth = (size_t)self.size.width; 20 | const size_t originalHeight = (size_t)self.size.height; 21 | CGContextRef bmContext = NYXCreateARGBBitmapContext(originalWidth, originalHeight, 0); 22 | if (!bmContext) 23 | return nil; 24 | 25 | /// Image quality 26 | CGContextSetShouldAntialias(bmContext, true); 27 | CGContextSetAllowsAntialiasing(bmContext, true); 28 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 29 | 30 | /// Image mask 31 | CGImageRef cgMaskImage = maskImage.CGImage; 32 | CGImageRef mask = CGImageMaskCreate((size_t)maskImage.size.width, (size_t)maskImage.size.height, CGImageGetBitsPerComponent(cgMaskImage), CGImageGetBitsPerPixel(cgMaskImage), CGImageGetBytesPerRow(cgMaskImage), CGImageGetDataProvider(cgMaskImage), NULL, false); 33 | 34 | /// Draw the original image in the bitmap context 35 | const CGRect r = (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = originalWidth, .size.height = originalHeight}; 36 | CGContextClipToMask(bmContext, r, cgMaskImage); 37 | CGContextDrawImage(bmContext, r, self.CGImage); 38 | 39 | /// Get the CGImage object 40 | CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(bmContext); 41 | /// Apply the mask 42 | CGImageRef maskedImageRef = CGImageCreateWithMask(imageRefWithAlpha, mask); 43 | 44 | UIImage* result = [UIImage imageWithCGImage:maskedImageRef]; 45 | 46 | /// Cleanup 47 | CGImageRelease(maskedImageRef); 48 | CGImageRelease(imageRefWithAlpha); 49 | CGContextRelease(bmContext); 50 | CGImageRelease(mask); 51 | 52 | return result; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Reflection.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Reflection.h 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter (@myell0w) on 02.06.11. 6 | 7 | // This was taken from the increadibly awesome HockeyKit: 8 | // Originally Created by Peter Steinberger on 10.01.11. 9 | // Copyright 2012 Peter Steinberger. All rights reserved. 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | #import "NYXImagesHelper.h" 31 | 32 | 33 | @interface UIImage (NYX_Reflection) 34 | 35 | -(UIImage*)reflectedImageWithHeight:(NSUInteger)height fromAlpha:(float)fromAlpha toAlpha:(float)toAlpha; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Reflection.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Reflection.m 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter (@myell0w) on 02.06.11. 6 | 7 | // This was taken from the increadibly awesome HockeyKit: 8 | // Originally Created by Peter Steinberger on 10.01.11. 9 | // Copyright 2012 Peter Steinberger. All rights reserved. 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | 30 | #import "UIImage+Reflection.h" 31 | 32 | 33 | @implementation UIImage (NYX_Reflection) 34 | 35 | -(UIImage*)reflectedImageWithHeight:(NSUInteger)height fromAlpha:(float)fromAlpha toAlpha:(float)toAlpha 36 | { 37 | if (!height) 38 | return nil; 39 | 40 | // create a bitmap graphics context the size of the image 41 | UIGraphicsBeginImageContextWithOptions((CGSize){.width = self.size.width, .height = height}, NO, 0.0f); 42 | CGContextRef mainViewContentContext = UIGraphicsGetCurrentContext(); 43 | 44 | // create a 2 bit CGImage containing a gradient that will be used for masking the 45 | // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask 46 | // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient 47 | CGImageRef gradientMaskImage = NYXCreateGradientImage(1, height, fromAlpha, toAlpha); 48 | 49 | // create an image by masking the bitmap of the mainView content with the gradient view 50 | // then release the pre-masked content bitmap and the gradient bitmap 51 | CGContextClipToMask(mainViewContentContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = self.size.width, .size.height = height}, gradientMaskImage); 52 | CGImageRelease(gradientMaskImage); 53 | 54 | // draw the image into the bitmap context 55 | CGContextDrawImage(mainViewContentContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size = self.size}, self.CGImage); 56 | 57 | // convert the finished reflection image to a UIImage 58 | UIImage* theImage = UIGraphicsGetImageFromCurrentImageContext(); 59 | 60 | UIGraphicsEndImageContext(); 61 | 62 | return theImage; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Resizing.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Resize.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | typedef enum 15 | { 16 | NYXCropModeTopLeft, 17 | NYXCropModeTopCenter, 18 | NYXCropModeTopRight, 19 | NYXCropModeBottomLeft, 20 | NYXCropModeBottomCenter, 21 | NYXCropModeBottomRight, 22 | NYXCropModeLeftCenter, 23 | NYXCropModeRightCenter, 24 | NYXCropModeCenter 25 | } NYXCropMode; 26 | 27 | 28 | @interface UIImage (NYX_Resizing) 29 | 30 | -(UIImage*)cropToSize:(CGSize)newSize usingMode:(NYXCropMode)cropMode; 31 | 32 | -(UIImage*)cropToSize:(CGSize)newSize; 33 | 34 | -(UIImage*)scaleByFactor:(float)scaleFactor; 35 | 36 | -(UIImage*)scaleToFitSize:(CGSize)newSize; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Resizing.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Resize.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Resizing.h" 12 | 13 | 14 | @implementation UIImage (NYX_Resizing) 15 | 16 | -(UIImage*)cropToSize:(CGSize)newSize usingMode:(NYXCropMode)cropMode 17 | { 18 | const CGSize size = self.size; 19 | CGFloat x, y; 20 | switch (cropMode) 21 | { 22 | case NYXCropModeTopLeft: 23 | x = y = 0.0f; 24 | break; 25 | case NYXCropModeTopCenter: 26 | x = (size.width - newSize.width) * 0.5f; 27 | y = 0.0f; 28 | break; 29 | case NYXCropModeTopRight: 30 | x = size.width - newSize.width; 31 | y = 0.0f; 32 | break; 33 | case NYXCropModeBottomLeft: 34 | x = 0.0f; 35 | y = size.height - newSize.height; 36 | break; 37 | case NYXCropModeBottomCenter: 38 | x = newSize.width * 0.5f; 39 | y = size.height - newSize.height; 40 | break; 41 | case NYXCropModeBottomRight: 42 | x = size.width - newSize.width; 43 | y = size.height - newSize.height; 44 | break; 45 | case NYXCropModeLeftCenter: 46 | x = 0.0f; 47 | y = (size.height - newSize.height) * 0.5f; 48 | break; 49 | case NYXCropModeRightCenter: 50 | x = size.width - newSize.width; 51 | y = (size.height - newSize.height) * 0.5f; 52 | break; 53 | case NYXCropModeCenter: 54 | x = (size.width - newSize.width) * 0.5f; 55 | y = (size.height - newSize.height) * 0.5f; 56 | break; 57 | default: // Default to top left 58 | x = y = 0.0f; 59 | break; 60 | } 61 | 62 | CGRect cropRect = CGRectMake(x * self.scale, y * self.scale, newSize.width * self.scale, newSize.height * self.scale); 63 | 64 | /// Create the cropped image 65 | CGImageRef croppedImageRef = CGImageCreateWithImageInRect(self.CGImage, cropRect); 66 | UIImage* cropped = [UIImage imageWithCGImage:croppedImageRef scale:self.scale orientation:self.imageOrientation]; 67 | 68 | /// Cleanup 69 | CGImageRelease(croppedImageRef); 70 | 71 | return cropped; 72 | } 73 | 74 | /* Convenience method to crop the image from the top left corner */ 75 | -(UIImage*)cropToSize:(CGSize)newSize 76 | { 77 | return [self cropToSize:newSize usingMode:NYXCropModeTopLeft]; 78 | } 79 | 80 | -(UIImage*)scaleByFactor:(float)scaleFactor 81 | { 82 | const size_t originalWidth = (size_t)(self.size.width * scaleFactor); 83 | const size_t originalHeight = (size_t)(self.size.height * scaleFactor); 84 | /// Number of bytes per row, each pixel in the bitmap will be represented by 4 bytes (ARGB), 8 bits of alpha/red/green/blue 85 | const size_t bytesPerRow = originalWidth * kNyxNumberOfComponentsPerARBGPixel; 86 | 87 | /// Create an ARGB bitmap context 88 | CGContextRef bmContext = NYXCreateARGBBitmapContext(originalWidth, originalHeight, bytesPerRow); 89 | if (!bmContext) 90 | return nil; 91 | 92 | /// Handle orientation 93 | if (UIImageOrientationLeft == self.imageOrientation) 94 | { 95 | CGContextRotateCTM(bmContext, (CGFloat)M_PI_2); 96 | CGContextTranslateCTM(bmContext, 0, -originalHeight); 97 | } 98 | else if (UIImageOrientationRight == self.imageOrientation) 99 | { 100 | CGContextRotateCTM(bmContext, (CGFloat)-M_PI_2); 101 | CGContextTranslateCTM(bmContext, -originalWidth, 0); 102 | } 103 | else if (UIImageOrientationDown == self.imageOrientation) 104 | { 105 | CGContextTranslateCTM(bmContext, originalWidth, originalHeight); 106 | CGContextRotateCTM(bmContext, (CGFloat)-M_PI); 107 | } 108 | 109 | /// Image quality 110 | CGContextSetShouldAntialias(bmContext, true); 111 | CGContextSetAllowsAntialiasing(bmContext, true); 112 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 113 | 114 | /// Draw the image in the bitmap context 115 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = originalWidth, .size.height = originalHeight}, self.CGImage); 116 | 117 | /// Create an image object from the context 118 | CGImageRef scaledImageRef = CGBitmapContextCreateImage(bmContext); 119 | UIImage* scaled = [UIImage imageWithCGImage:scaledImageRef]; 120 | 121 | /// Cleanup 122 | CGImageRelease(scaledImageRef); 123 | CGContextRelease(bmContext); 124 | 125 | return scaled; 126 | } 127 | 128 | -(UIImage*)scaleToFitSize:(CGSize)newSize 129 | { 130 | const size_t originalWidth = (size_t)self.size.width; 131 | const size_t originalHeight = (size_t)self.size.height; 132 | 133 | /// Keep aspect ratio 134 | size_t destWidth, destHeight; 135 | if (originalWidth > originalHeight) 136 | { 137 | destWidth = (size_t)newSize.width; 138 | destHeight = (size_t)(originalHeight * newSize.width / originalWidth); 139 | } 140 | else 141 | { 142 | destHeight = (size_t)newSize.height; 143 | destWidth = (size_t)(originalWidth * newSize.height / originalHeight); 144 | } 145 | if (destWidth > newSize.width) 146 | { 147 | destWidth = (size_t)newSize.width; 148 | destHeight = (size_t)(originalHeight * newSize.width / originalWidth); 149 | } 150 | if (destHeight > newSize.height) 151 | { 152 | destHeight = (size_t)newSize.height; 153 | destWidth = (size_t)(originalWidth * newSize.height / originalHeight); 154 | } 155 | 156 | /// Create an ARGB bitmap context 157 | CGContextRef bmContext = NYXCreateARGBBitmapContext(destWidth, destHeight, destWidth * kNyxNumberOfComponentsPerARBGPixel); 158 | if (!bmContext) 159 | return nil; 160 | 161 | /// Image quality 162 | CGContextSetShouldAntialias(bmContext, true); 163 | CGContextSetAllowsAntialiasing(bmContext, true); 164 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 165 | 166 | /// Draw the image in the bitmap context 167 | 168 | UIGraphicsPushContext(bmContext); 169 | CGContextTranslateCTM(bmContext, 0.0f, destHeight); 170 | CGContextScaleCTM(bmContext, 1.0f, -1.0f); 171 | [self drawInRect:(CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = destWidth, .size.height = destHeight}]; 172 | UIGraphicsPopContext(); 173 | 174 | /// Create an image object from the context 175 | CGImageRef scaledImageRef = CGBitmapContextCreateImage(bmContext); 176 | UIImage* scaled = [UIImage imageWithCGImage:scaledImageRef]; 177 | 178 | /// Cleanup 179 | CGImageRelease(scaledImageRef); 180 | CGContextRelease(bmContext); 181 | 182 | return scaled; 183 | } 184 | 185 | @end 186 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Rotating.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Rotation.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | @interface UIImage (NYX_Rotating) 15 | 16 | -(UIImage*)rotateInRadians:(float)radians; 17 | 18 | -(UIImage*)rotateInDegrees:(float)degrees; 19 | 20 | -(UIImage*)rotateImagePixelsInRadians:(float)radians; 21 | 22 | -(UIImage*)rotateImagePixelsInDegrees:(float)degrees; 23 | 24 | -(UIImage*)verticalFlip; 25 | 26 | -(UIImage*)horizontalFlip; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Rotating.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Rotation.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Rotating.h" 12 | #import 13 | #import 14 | 15 | 16 | @implementation UIImage (NYX_Rotating) 17 | 18 | -(UIImage*)rotateInRadians:(float)radians 19 | { 20 | const size_t width = (size_t)(self.size.width * self.scale); 21 | const size_t height = (size_t)(self.size.height * self.scale); 22 | 23 | CGRect imgRect = (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}; 24 | CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, CGAffineTransformMakeRotation(radians)); 25 | 26 | /// Create an ARGB bitmap context 27 | CGContextRef bmContext = NYXCreateARGBBitmapContext((size_t)rotatedRect.size.width, (size_t)rotatedRect.size.height, 0); 28 | if (!bmContext) 29 | return nil; 30 | 31 | CGContextSetShouldAntialias(bmContext, true); 32 | CGContextSetAllowsAntialiasing(bmContext, true); 33 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 34 | 35 | /// Rotation happen here (around the center) 36 | CGContextTranslateCTM(bmContext, +(rotatedRect.size.width * 0.5f), +(rotatedRect.size.height * 0.5f)); 37 | CGContextRotateCTM(bmContext, radians); 38 | 39 | /// Draw the image in the bitmap context 40 | CGContextDrawImage(bmContext, (CGRect){.origin.x = -(width * 0.5f), .origin.y = -(height * 0.5f), .size.width = width, .size.height = height}, self.CGImage); 41 | 42 | /// Create an image object from the context 43 | CGImageRef rotatedImageRef = CGBitmapContextCreateImage(bmContext); 44 | UIImage* rotated = [UIImage imageWithCGImage:rotatedImageRef scale:self.scale orientation:self.imageOrientation]; 45 | 46 | /// Cleanup 47 | CGImageRelease(rotatedImageRef); 48 | CGContextRelease(bmContext); 49 | 50 | return rotated; 51 | } 52 | 53 | -(UIImage*)rotateInDegrees:(float)degrees 54 | { 55 | return [self rotateInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)]; 56 | } 57 | 58 | -(UIImage*)rotateImagePixelsInRadians:(float)radians 59 | { 60 | /// Create an ARGB bitmap context 61 | const size_t width = (size_t)(self.size.width * self.scale); 62 | const size_t height = (size_t)(self.size.height * self.scale); 63 | const size_t bytesPerRow = width * kNyxNumberOfComponentsPerARBGPixel; 64 | CGContextRef bmContext = NYXCreateARGBBitmapContext(width, height, bytesPerRow); 65 | if (!bmContext) 66 | return nil; 67 | 68 | /// Draw the image in the bitmap context 69 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = height}, self.CGImage); 70 | 71 | /// Grab the image raw data 72 | UInt8* data = (UInt8*)CGBitmapContextGetData(bmContext); 73 | if (!data) 74 | { 75 | CGContextRelease(bmContext); 76 | return nil; 77 | } 78 | 79 | vImage_Buffer src = {data, height, width, bytesPerRow}; 80 | vImage_Buffer dest = {data, height, width, bytesPerRow}; 81 | Pixel_8888 bgColor = {0, 0, 0, 0}; 82 | vImageRotate_ARGB8888(&src, &dest, NULL, radians, bgColor, kvImageBackgroundColorFill); 83 | 84 | CGImageRef rotatedImageRef = CGBitmapContextCreateImage(bmContext); 85 | UIImage* rotated = [UIImage imageWithCGImage:rotatedImageRef scale:self.scale orientation:self.imageOrientation]; 86 | 87 | /// Cleanup 88 | CGImageRelease(rotatedImageRef); 89 | CGContextRelease(bmContext); 90 | 91 | return rotated; 92 | } 93 | 94 | -(UIImage*)rotateImagePixelsInDegrees:(float)degrees 95 | { 96 | return [self rotateImagePixelsInRadians:(float)NYX_DEGREES_TO_RADIANS(degrees)]; 97 | } 98 | 99 | -(UIImage*)verticalFlip 100 | { 101 | /// Create an ARGB bitmap context 102 | const size_t originalWidth = (size_t)(self.size.width * self.scale); 103 | const size_t originalHeight = (size_t)(self.size.height * self.scale); 104 | CGContextRef bmContext = NYXCreateARGBBitmapContext(originalWidth, originalHeight, originalWidth * kNyxNumberOfComponentsPerARBGPixel); 105 | if (!bmContext) 106 | return nil; 107 | 108 | /// Image quality 109 | CGContextSetShouldAntialias(bmContext, true); 110 | CGContextSetAllowsAntialiasing(bmContext, true); 111 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 112 | 113 | CGContextTranslateCTM(bmContext, 0.0f, originalHeight); 114 | CGContextScaleCTM(bmContext, 1.0f, -1.0f); 115 | 116 | /// Draw the image in the bitmap context 117 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0, .size.width = originalWidth, .size.height = originalHeight}, self.CGImage); 118 | 119 | /// Create an image object from the context 120 | CGImageRef flippedImageRef = CGBitmapContextCreateImage(bmContext); 121 | UIImage* flipped = [UIImage imageWithCGImage:flippedImageRef scale:self.scale orientation:self.imageOrientation]; 122 | 123 | /// Cleanup 124 | CGImageRelease(flippedImageRef); 125 | CGContextRelease(bmContext); 126 | 127 | return flipped; 128 | } 129 | 130 | -(UIImage*)horizontalFlip 131 | { 132 | /// Create an ARGB bitmap context 133 | const size_t originalWidth = (size_t)(self.size.width * self.scale); 134 | const size_t originalHeight = (size_t)(self.size.height * self.scale); 135 | CGContextRef bmContext = NYXCreateARGBBitmapContext(originalWidth, originalHeight, originalWidth * kNyxNumberOfComponentsPerARBGPixel); 136 | if (!bmContext) 137 | return nil; 138 | 139 | /// Image quality 140 | CGContextSetShouldAntialias(bmContext, true); 141 | CGContextSetAllowsAntialiasing(bmContext, true); 142 | CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh); 143 | 144 | CGContextTranslateCTM(bmContext, originalWidth, 0.0f); 145 | CGContextScaleCTM(bmContext, -1.0f, 1.0f); 146 | 147 | /// Draw the image in the bitmap context 148 | CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = originalWidth, .size.height = originalHeight}, self.CGImage); 149 | 150 | /// Create an image object from the context 151 | CGImageRef flippedImageRef = CGBitmapContextCreateImage(bmContext); 152 | UIImage* flipped = [UIImage imageWithCGImage:flippedImageRef scale:self.scale orientation:self.imageOrientation]; 153 | 154 | /// Cleanup 155 | CGImageRelease(flippedImageRef); 156 | CGContextRelease(bmContext); 157 | 158 | return flipped; 159 | } 160 | 161 | @end 162 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Saving.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Saving.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 05/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "NYXImagesHelper.h" 12 | 13 | 14 | typedef enum 15 | { 16 | NYXImageTypePNG, 17 | NYXImageTypeJPEG, 18 | NYXImageTypeGIF, 19 | NYXImageTypeBMP, 20 | NYXImageTypeTIFF 21 | } NYXImageType; 22 | 23 | 24 | @interface UIImage (NYX_Saving) 25 | 26 | -(BOOL)saveToURL:(NSURL*)url uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor; 27 | 28 | -(BOOL)saveToURL:(NSURL*)url type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor; 29 | 30 | -(BOOL)saveToURL:(NSURL*)url; 31 | 32 | -(BOOL)saveToPath:(NSString*)path uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor; 33 | 34 | -(BOOL)saveToPath:(NSString*)path type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor; 35 | 36 | -(BOOL)saveToPath:(NSString*)path; 37 | 38 | -(BOOL)saveToPhotosAlbum; 39 | 40 | +(NSString*)extensionForUTI:(CFStringRef)uti; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+Saving.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Saving.m 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 05/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Saving.h" 12 | #import // For CGImageDestination 13 | #import // For the UTI types constants 14 | #import // For photos album saving 15 | 16 | 17 | @interface UIImage (NYX_Saving_private) 18 | -(CFStringRef)utiForType:(NYXImageType)type; 19 | @end 20 | 21 | 22 | @implementation UIImage (NYX_Saving) 23 | 24 | -(BOOL)saveToURL:(NSURL*)url uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor 25 | { 26 | if (!url) 27 | return NO; 28 | 29 | if (!uti) 30 | uti = kUTTypePNG; 31 | 32 | CGImageDestinationRef dest = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, uti, 1, NULL); 33 | if (!dest) 34 | return NO; 35 | 36 | /// Set the options, 1 -> lossless 37 | CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 38 | if (!options) 39 | { 40 | CFRelease(dest); 41 | return NO; 42 | } 43 | CFDictionaryAddValue(options, kCGImageDestinationLossyCompressionQuality, (__bridge CFNumberRef)[NSNumber numberWithFloat:1.0f]); // No compression 44 | if (fillColor) 45 | CFDictionaryAddValue(options, kCGImageDestinationBackgroundColor, fillColor.CGColor); 46 | 47 | /// Add the image 48 | CGImageDestinationAddImage(dest, self.CGImage, (CFDictionaryRef)options); 49 | 50 | /// Write it to the destination 51 | const bool success = CGImageDestinationFinalize(dest); 52 | 53 | /// Cleanup 54 | CFRelease(options); 55 | CFRelease(dest); 56 | 57 | return success; 58 | } 59 | 60 | -(BOOL)saveToURL:(NSURL*)url type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor 61 | { 62 | return [self saveToURL:url uti:[self utiForType:type] backgroundFillColor:fillColor]; 63 | } 64 | 65 | -(BOOL)saveToURL:(NSURL*)url 66 | { 67 | return [self saveToURL:url uti:kUTTypePNG backgroundFillColor:nil]; 68 | } 69 | 70 | -(BOOL)saveToPath:(NSString*)path uti:(CFStringRef)uti backgroundFillColor:(UIColor*)fillColor 71 | { 72 | if (!path) 73 | return NO; 74 | 75 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 76 | const BOOL ret = [self saveToURL:url uti:uti backgroundFillColor:fillColor]; 77 | return ret; 78 | } 79 | 80 | -(BOOL)saveToPath:(NSString*)path type:(NYXImageType)type backgroundFillColor:(UIColor*)fillColor 81 | { 82 | if (!path) 83 | return NO; 84 | 85 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 86 | const BOOL ret = [self saveToURL:url uti:[self utiForType:type] backgroundFillColor:fillColor]; 87 | return ret; 88 | } 89 | 90 | -(BOOL)saveToPath:(NSString*)path 91 | { 92 | if (!path) 93 | return NO; 94 | 95 | NSURL* url = [[NSURL alloc] initFileURLWithPath:path]; 96 | const BOOL ret = [self saveToURL:url type:NYXImageTypePNG backgroundFillColor:nil]; 97 | return ret; 98 | } 99 | 100 | -(BOOL)saveToPhotosAlbum 101 | { 102 | ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 103 | __block BOOL ret = YES; 104 | [library writeImageToSavedPhotosAlbum:self.CGImage orientation:(ALAssetOrientation)self.imageOrientation completionBlock:^(NSURL* assetURL, NSError* error) { 105 | if (!assetURL) 106 | { 107 | NSLog(@"%@", error); 108 | ret = NO; 109 | } 110 | }]; 111 | return ret; 112 | } 113 | 114 | +(NSString*)extensionForUTI:(CFStringRef)uti 115 | { 116 | if (!uti) 117 | return nil; 118 | 119 | NSDictionary* declarations = (__bridge_transfer NSDictionary*)UTTypeCopyDeclaration(uti); 120 | if (!declarations) 121 | return nil; 122 | 123 | id extensions = [(NSDictionary*)[declarations objectForKey:(__bridge NSString*)kUTTypeTagSpecificationKey] objectForKey:(__bridge NSString*)kUTTagClassFilenameExtension]; 124 | NSString* extension = ([extensions isKindOfClass:[NSArray class]]) ? [extensions objectAtIndex:0] : extensions; 125 | 126 | return extension; 127 | } 128 | 129 | #pragma mark - Private 130 | -(CFStringRef)utiForType:(NYXImageType)type 131 | { 132 | CFStringRef uti = NULL; 133 | switch (type) 134 | { 135 | case NYXImageTypeBMP: 136 | uti = kUTTypeBMP; 137 | break; 138 | case NYXImageTypeJPEG: 139 | uti = kUTTypeJPEG; 140 | break; 141 | case NYXImageTypePNG: 142 | uti = kUTTypePNG; 143 | break; 144 | case NYXImageTypeTIFF: 145 | uti = kUTTypeTIFF; 146 | break; 147 | case NYXImageTypeGIF: 148 | uti = kUTTypeGIF; 149 | break; 150 | default: 151 | uti = kUTTypePNG; 152 | break; 153 | } 154 | return uti; 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+fixOrientation.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage.h 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 12-11-28. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage(fixOrientation) 12 | - (UIImage *)fixOrientation:(UIImage *)aImage; 13 | @end 14 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Categories/UIImage+fixOrientation.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage.m 3 | // SinaMBlog 4 | // 5 | // Created by jimney on 12-11-28. 6 | // Copyright (c) 2013年 jimneylee. All rights reserved. 7 | // 8 | 9 | #import "UIImage+fixOrientation.h" 10 | 11 | @implementation UIImage(fixOrientation) 12 | 13 | - (UIImage *)fixOrientation:(UIImage *)aImage { 14 | 15 | // No-op if the orientation is already correct 16 | if (aImage.imageOrientation == UIImageOrientationUp) 17 | return aImage; 18 | 19 | // We need to calculate the proper transformation to make the image upright. 20 | // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 21 | CGAffineTransform transform = CGAffineTransformIdentity; 22 | 23 | switch (aImage.imageOrientation) { 24 | case UIImageOrientationDown: 25 | case UIImageOrientationDownMirrored: 26 | transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height); 27 | transform = CGAffineTransformRotate(transform, M_PI); 28 | break; 29 | 30 | case UIImageOrientationLeft: 31 | case UIImageOrientationLeftMirrored: 32 | transform = CGAffineTransformTranslate(transform, aImage.size.width, 0); 33 | transform = CGAffineTransformRotate(transform, M_PI_2); 34 | break; 35 | 36 | case UIImageOrientationRight: 37 | case UIImageOrientationRightMirrored: 38 | transform = CGAffineTransformTranslate(transform, 0, aImage.size.height); 39 | transform = CGAffineTransformRotate(transform, -M_PI_2); 40 | break; 41 | default: 42 | break; 43 | } 44 | 45 | switch (aImage.imageOrientation) { 46 | case UIImageOrientationUpMirrored: 47 | case UIImageOrientationDownMirrored: 48 | transform = CGAffineTransformTranslate(transform, aImage.size.width, 0); 49 | transform = CGAffineTransformScale(transform, -1, 1); 50 | break; 51 | 52 | case UIImageOrientationLeftMirrored: 53 | case UIImageOrientationRightMirrored: 54 | transform = CGAffineTransformTranslate(transform, aImage.size.height, 0); 55 | transform = CGAffineTransformScale(transform, -1, 1); 56 | break; 57 | default: 58 | break; 59 | } 60 | 61 | // Now we draw the underlying CGImage into a new context, applying the transform 62 | // calculated above. 63 | CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height, 64 | CGImageGetBitsPerComponent(aImage.CGImage), 0, 65 | CGImageGetColorSpace(aImage.CGImage), 66 | CGImageGetBitmapInfo(aImage.CGImage)); 67 | CGContextConcatCTM(ctx, transform); 68 | switch (aImage.imageOrientation) { 69 | case UIImageOrientationLeft: 70 | case UIImageOrientationLeftMirrored: 71 | case UIImageOrientationRight: 72 | case UIImageOrientationRightMirrored: 73 | // Grr... 74 | CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage); 75 | break; 76 | 77 | default: 78 | CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage); 79 | break; 80 | } 81 | 82 | // And now we just create a new UIImage from the drawing context 83 | CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 84 | UIImage *img = [UIImage imageWithCGImage:cgimg]; 85 | CGContextRelease(ctx); 86 | CGImageRelease(cgimg); 87 | return img; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Helper/NYXImagesHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesHelper.h 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter on 02/06/11. 6 | // Originally Created by @Nyx0uf on 02/05/11. 7 | // Copyright 2012 Nyx0uf. All rights reserved. 8 | // www.cocoaintheshell.com 9 | // 10 | 11 | 12 | /* Number of components for an opaque grey colorSpace = 3 */ 13 | #define kNyxNumberOfComponentsPerGreyPixel 3 14 | /* Number of components for an ARGB pixel (Alpha / Red / Green / Blue) = 4 */ 15 | #define kNyxNumberOfComponentsPerARBGPixel 4 16 | /* Minimun value for a pixel component */ 17 | #define kNyxMinPixelComponentValue (UInt8)0 18 | /* Maximum value for a pixel component */ 19 | #define kNyxMaxPixelComponentValue (UInt8)255 20 | 21 | /* Convert degrees value to radians */ 22 | #define NYX_DEGREES_TO_RADIANS(__DEGREES) (__DEGREES * 0.017453293) // (M_PI / 180.0f) 23 | /* Convert radians value to degrees */ 24 | #define NYX_RADIANS_TO_DEGREES(__RADIANS) (__RADIANS * 57.295779513) // (180.0f / M_PI) 25 | 26 | /* Returns the lower value */ 27 | #define NYX_MIN(__A, __B) ((__A) < (__B) ? (__A) : (__B)) 28 | /* Returns the higher value */ 29 | #define NYX_MAX(__A ,__B) ((__A) > (__B) ? (__A) : (__B)) 30 | /* Returns a correct value for a pixel component (0 - 255) */ 31 | #define NYX_SAFE_PIXEL_COMPONENT_VALUE(__COLOR) (NYX_MIN(kNyxMaxPixelComponentValue, NYX_MAX(kNyxMinPixelComponentValue, __COLOR))) 32 | 33 | /* iOS version runtime check */ 34 | #define NYX_IOS_VERSION_LESS_THAN(__VERSIONSTRING) ([[[UIDevice currentDevice] systemVersion] compare:__VERSIONSTRING options:NSNumericSearch] == NSOrderedAscending) 35 | 36 | /* dispatch_release() not needed in iOS 6+ original idea from FMDB https://github.com/ccgus/fmdb/commit/aef763eeb64e6fa654e7d121f1df4c16a98d9f4f */ 37 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 38 | #define NYX_DISPATCH_RELEASE(__QUEUE) 39 | #else 40 | #define NYX_DISPATCH_RELEASE(__QUEUE) (dispatch_release(__QUEUE)) 41 | #endif 42 | 43 | CGContextRef NYXCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow); 44 | CGImageRef NYXCreateGradientImage(const size_t pixelsWide, const size_t pixelsHigh, const CGFloat fromAlpha, const CGFloat toAlpha); 45 | CIContext* NYXGetCIContext(void); 46 | CGColorSpaceRef NYXGetRGBColorSpace(void); 47 | void NYXImagesKitRelease(void); 48 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Helper/NYXImagesHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesHelper.m 3 | // NYXImagesKit 4 | // 5 | // Created by Matthias Tretter on 02/06/11. 6 | // Originally Created by @Nyx0uf on 02/05/11. 7 | // Copyright 2012 Nyx0uf. All rights reserved. 8 | // www.cocoaintheshell.com 9 | // 10 | 11 | 12 | #import "NYXImagesHelper.h" 13 | 14 | 15 | static CIContext* __ciContext = nil; 16 | static CGColorSpaceRef __rgbColorSpace = NULL; 17 | 18 | 19 | CGContextRef NYXCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow) 20 | { 21 | /// Use the generic RGB color space 22 | /// We avoid the NULL check because CGColorSpaceRelease() NULL check the value anyway, and worst case scenario = fail to create context 23 | /// Create the bitmap context, we want pre-multiplied ARGB, 8-bits per component 24 | CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8/*Bits per component*/, bytesPerRow, NYXGetRGBColorSpace(), kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); 25 | 26 | return bmContext; 27 | } 28 | 29 | // The following function was taken from the increadibly awesome HockeyKit 30 | // Created by Peter Steinberger on 10.01.11. 31 | // Copyright 2012 Peter Steinberger. All rights reserved. 32 | CGImageRef NYXCreateGradientImage(const size_t pixelsWide, const size_t pixelsHigh, const CGFloat fromAlpha, const CGFloat toAlpha) 33 | { 34 | // gradient is always black-white and the mask must be in the gray colorspace 35 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); 36 | 37 | // create the bitmap context 38 | CGContextRef gradientBitmapContext = CGBitmapContextCreate(NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace, kCGImageAlphaNone); 39 | 40 | // define the start and end grayscale values (with the alpha, even though 41 | // our bitmap context doesn't support alpha the gradient requires it) 42 | CGFloat colors[] = {toAlpha, 1.0f, fromAlpha, 1.0f}; 43 | 44 | // create the CGGradient and then release the gray color space 45 | CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2); 46 | CGColorSpaceRelease(colorSpace); 47 | 48 | // create the start and end points for the gradient vector (straight down) 49 | CGPoint gradientEndPoint = CGPointZero; 50 | CGPoint gradientStartPoint = (CGPoint){.x = 0.0f, .y = pixelsHigh}; 51 | 52 | // draw the gradient into the gray bitmap context 53 | CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint, gradientEndPoint, kCGGradientDrawsAfterEndLocation); 54 | CGGradientRelease(grayScaleGradient); 55 | 56 | // convert the context into a CGImageRef and release the context 57 | CGImageRef theCGImage = CGBitmapContextCreateImage(gradientBitmapContext); 58 | CGContextRelease(gradientBitmapContext); 59 | 60 | // return the imageref containing the gradient 61 | return theCGImage; 62 | } 63 | 64 | CIContext* NYXGetCIContext(void) 65 | { 66 | if (!__ciContext) 67 | { 68 | NSNumber* num = [[NSNumber alloc] initWithBool:NO]; 69 | NSDictionary* opts = [[NSDictionary alloc] initWithObjectsAndKeys:num, kCIContextUseSoftwareRenderer, nil]; 70 | __ciContext = [CIContext contextWithOptions:opts]; 71 | } 72 | return __ciContext; 73 | } 74 | 75 | CGColorSpaceRef NYXGetRGBColorSpace(void) 76 | { 77 | if (!__rgbColorSpace) 78 | { 79 | __rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 80 | } 81 | return __rgbColorSpace; 82 | } 83 | 84 | void NYXImagesKitRelease(void) 85 | { 86 | if (__rgbColorSpace) 87 | CGColorSpaceRelease(__rgbColorSpace), __rgbColorSpace = NULL; 88 | if (__ciContext) 89 | __ciContext = nil; 90 | } 91 | -------------------------------------------------------------------------------- /vendor/NYXImagesKit/Helper/NYXImagesKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NYXImagesKit.h 3 | // NYXImagesKit 4 | // 5 | // Created by @Nyx0uf on 02/05/11. 6 | // Copyright 2012 Nyx0uf. All rights reserved. 7 | // www.cocoaintheshell.com 8 | // 9 | 10 | 11 | #import "UIImage+Blurring.h" 12 | #import "UIImage+Enhancing.h" 13 | #import "UIImage+Filtering.h" 14 | #import "UIImage+Masking.h" 15 | #import "UIImage+Reflection.h" 16 | #import "UIImage+Resizing.h" 17 | #import "UIImage+Rotating.h" 18 | #import "UIImage+Saving.h" 19 | #import "NYXProgressiveImageView.h" 20 | -------------------------------------------------------------------------------- /vendor/Pinyin/pinyin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pinyin.h 3 | * Chinese Pinyin First Letter 4 | * 5 | * Created by George on 4/21/10. 6 | * Copyright 2010 RED/SAFI. All rights reserved. 7 | * 8 | */ 9 | 10 | /* 11 | * // Example 12 | * 13 | * #import "pinyin.h" 14 | * 15 | * NSString *hanyu = @"中国共产党万岁!"; 16 | * for (int i = 0; i < [hanyu length]; i++) 17 | * { 18 | * printf("%c", pinyinFirstLetter([hanyu characterAtIndex:i])); 19 | * } 20 | * 21 | */ 22 | #define ALPHA @"ABCDEFGHIJKLMNOPQRSTUVWXYZ#" 23 | char pinyinFirstLetter(unsigned short hanzi); 24 | int isFirstLetterHANZI(unsigned short hanzi); -------------------------------------------------------------------------------- /vendor/UIScrollView+ZoomToPoint/UIScrollView+ZoomToPoint.h: -------------------------------------------------------------------------------- 1 | 2 | //copy from here: https://gist.github.com/TimOliver/6138097 3 | @interface UIScrollView (ZoomToPoint) 4 | 5 | - (void)zoomToPoint:(CGPoint)zoomPoint withScale: (CGFloat)scale animated: (BOOL)animated; 6 | 7 | @end -------------------------------------------------------------------------------- /vendor/UIScrollView+ZoomToPoint/UIScrollView+ZoomToPoint.m: -------------------------------------------------------------------------------- 1 | 2 | #import "UIScrollView+ZoomToPoint.h" 3 | 4 | @implementation UIScrollView (ZoomToPoint) 5 | 6 | - (void)zoomToPoint:(CGPoint)zoomPoint withScale: (CGFloat)scale animated: (BOOL)animated 7 | { 8 | //Normalize current content size back to content scale of 1.0f 9 | CGSize contentSize; 10 | contentSize.width = (self.contentSize.width / self.zoomScale); 11 | contentSize.height = (self.contentSize.height / self.zoomScale); 12 | 13 | //translate the zoom point to relative to the content rect 14 | zoomPoint.x = (zoomPoint.x / self.bounds.size.width) * contentSize.width; 15 | zoomPoint.y = (zoomPoint.y / self.bounds.size.height) * contentSize.height; 16 | 17 | //derive the size of the region to zoom to 18 | CGSize zoomSize; 19 | zoomSize.width = self.bounds.size.width / scale; 20 | zoomSize.height = self.bounds.size.height / scale; 21 | 22 | //offset the zoom rect so the actual zoom point is in the middle of the rectangle 23 | CGRect zoomRect; 24 | zoomRect.origin.x = zoomPoint.x - zoomSize.width / 2.0f; 25 | zoomRect.origin.y = zoomPoint.y - zoomSize.height / 2.0f; 26 | zoomRect.size.width = zoomSize.width; 27 | zoomRect.size.height = zoomSize.height; 28 | 29 | //apply the resize 30 | [self zoomToRect: zoomRect animated: animated]; 31 | } 32 | 33 | @end -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/close.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/close@2x.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_keyboardbutton_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_keyboardbutton_background.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_keyboardbutton_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_keyboardbutton_background@2x.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_toolbar_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_toolbar_background.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_toolbar_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/compose_toolbar_background@2x.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background@2x.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background_os7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background_os7.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background_os7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/WeiboSDK.bundle/images/navigationbar_background_os7@2x.png -------------------------------------------------------------------------------- /vendor/libWeiboSDK/libWeiboSDK.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jimneylee/JLSinaMBlogNimbus/d690a3c3e1b10bcd766b79c96cf3c94437b1c580/vendor/libWeiboSDK/libWeiboSDK.a --------------------------------------------------------------------------------