├── .gitignore
├── .idea
└── codeStyleSettings.xml
├── LICENSE
├── Podfile
├── README.md
├── RKNotificationHub.podspec
├── RKNotificationHub.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── RKNotificationHub.xccheckout
│ └── xcuserdata
│ │ └── cwrichardkim93.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── cwrichardkim93.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── RKNotificationHub.xcscheme
│ └── xcschememanagement.plist
├── RKNotificationHub
├── AppDelegate.h
├── AppDelegate.m
├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── LaunchImage.launchimage
│ │ └── Contents.json
│ └── earth.imageset
│ │ ├── Contents.json
│ │ ├── earth-1-1.png
│ │ ├── earth-1.png
│ │ └── earth.png
├── Info.plist
├── RKNotificationHub.h
├── RKNotificationHub.m
├── ViewController.h
├── ViewController.m
└── main.m
└── RKNotificationHubTests
├── Info.plist
└── RKNotificationHubTests.m
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/.idea/codeStyleSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Choong-Won Richard Kim
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '6.0'
3 |
4 | target 'RKNotificationHub' do
5 |
6 | end
7 |
8 | target 'RKNotificationHubTests' do
9 |
10 | end
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | RKNotificationHub
2 | =================
3 |
4 | A way to quickly add a notification icon to a UIView (iOS6 and up). [Support](http://cwrichardkim.com)
5 |
6 | 
7 |
8 | Code:
9 | ``` objc
10 | RKNotificationHub* hub = [[RKNotificationHub alloc]initWithView:yourView]; // sets the count to 0
11 | [hub increment]; // increments the count to 1, making the notification visible
12 | ```
13 |
14 | ### Pod
15 | ```
16 | pod 'RKNotificationHub'
17 | ```
18 |
19 | ### USAGE
20 | 
21 | ``` objc
22 | [hub increment];
23 | ```
24 | ``` objc
25 | -(void)increment;
26 | -(void)incrementBy:(int)amount;
27 | -(void)decrement;
28 | -(void)decrementBy:(int)amount;
29 | @property (nonatomic, assign) int count; //%%% set to a certain number
30 | ```
31 |
32 | __Combine Actions!__
33 |
34 | 
35 | ``` objc
36 | [hub increment];
37 | [hub pop];
38 | ```
39 |
40 | ### CUSTOMIZE
41 | 
42 | ``` objc
43 | //%%% COLOR
44 | [hub setCircleColor:[UIColor colorWithRed:0.98 green:0.66 blue:0.2 alpha:1]
45 | labelColor:[UIColor whiteColor]];
46 | ```
47 |
48 | 
49 | ```objc
50 | //%%% CIRCLE FRAME
51 | [hub setCircleAtFrame:CGRectMake(-10, -10, 30, 30)]; //frame relative to the view you set it to
52 |
53 | //%%% MOVE FRAME
54 | [hub moveCircleByX:-5 Y:5]; // moves the circle 5 pixels left and down from its current position
55 |
56 | //%%% CIRCLE SIZE
57 | [hub scaleCircleSizeBy:2]; // doubles the size of the circle, keeps the same center
58 | ```
59 |
60 | 
61 | ``` objc
62 | //%%% BLANK BADGE
63 | [hub hideCount];
64 | /* shoutout to imkevinxu for this suggestion */
65 | ```
66 |
67 |
68 | ### TROUBLESHOOTING
69 | **Notification isn't showing up!**
70 | * If the hub value is < 1, the circle hides. Try calling `[increment]`
71 | * Make sure the view you set the hub to is visible (i.e. did you call `[self.view addSubview: yourView]`?)
72 | * Make sure you didn't call `[hideCount]` anywhere. Call `[showCount]` to counter this
73 |
74 | **It isn't incrementing / decrementing properly!**
75 | * I've written it so that any count < 1 doesn't show up. If you need help customizing this, reach out to me
76 |
77 | **The circle is in a weird place**
78 | * If you want to resize the circle, use `[scaleCircleSizeBy:]`. 0.5 will give you half the size, 2 will give you double
79 | * If the circle is just a few pixels off, use `[moveCircleByX: Y:]`. This shifts the circle by the number of pixels given
80 | * If you want to manually set the circle, call `[setCircleAtFrame:]` and give it your own CGRect
81 |
82 | **Something else isn't working properly**
83 | * Send me a tweet @cwRichardKim with #RKNotificationHub so that other people can search these issues too
84 | * Use github's issue reporter on the right
85 | * Send me an email cwRichardKim@gmail.com (might take a few days)
86 |
87 |
88 | ### Updates
89 | * 1.0.0 first release with cocoapod
90 | * 1.0.1 cocoapod allows iOS 7.0
91 | * 1.0.2 added "hideCount", "showCount", and "count" methods, allowing indeterminate badges with no number
92 | * 1.0.5 added bubble expansion for larger numbers [(gif)](http://i.imgur.com/cpQuShT.gif)
93 | * 2.0.0 changed count to `NSUInteger` (removed support for negative counts), made local constants `static const`
94 | * 2.0.1 iOS 6 compatability
95 | * 2.0.2 changed count back to 'int' for better swift compatability
96 | * 2.0.4 fixed cocoapod update issue
97 |
98 | ### Areas for Improvements / involvement
99 | * A mechanism for adding a custom animation
100 | * Singleton option
101 |
--------------------------------------------------------------------------------
/RKNotificationHub.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
4 | #
5 | # These will help people to find your library, and whilst it
6 | # can feel like a chore to fill in it's definitely to your advantage. The
7 | # summary should be tweet-length, and the description more in depth.
8 | #
9 |
10 | s.name = "RKNotificationHub"
11 | s.version = "2.0.5"
12 | s.summary = "iOS: Make any UIView a full fledged notification center"
13 |
14 | s.description = "A simple one line solution to turning adding a notification bubble to any UIView. Easily increment, decrement, an animate the notification, -Notification, -Notification Center, -objectivec, -ios, -iphone, -xcode"
15 |
16 | s.homepage = "https://github.com/cwRichardKim/RKNotificationHub"
17 | s.screenshots = "http://i.imgur.com/OlYystx.gif"
18 |
19 |
20 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
21 | #
22 | # Licensing your code is important. See http://choosealicense.com for more info.
23 | # CocoaPods will detect a license file if there is a named LICENSE*
24 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
25 | #
26 |
27 | # s.license = "MIT (example)"
28 | s.license = { :type => "MIT", :file => "LICENSE" }
29 |
30 |
31 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
32 | #
33 | # Specify the authors of the library, with email addresses. Email addresses
34 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
35 | # accepts just a name if you'd rather not provide an email address.
36 | #
37 | # Specify a social_media_url where others can refer to, for example a twitter
38 | # profile URL.
39 | #
40 |
41 | s.author = "cwrichardkim"
42 | # s.authors = { "cwrichardkim93" => "cwrichardkim93@gmail.com" }
43 | s.social_media_url = "http://twitter.com/cwrichardkim"
44 |
45 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
46 | #
47 | # If this Pod runs only on iOS or OS X, then specify the platform and
48 | # the deployment target. You can optionally include the target after the platform.
49 | #
50 |
51 | # s.platform = :ios
52 | s.platform = :ios, "6.0"
53 |
54 | # When using multiple platforms
55 | # s.ios.deployment_target = "5.0"
56 | # s.osx.deployment_target = "10.7"
57 |
58 |
59 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
60 | #
61 | # Specify the location from where the source should be retrieved.
62 | # Supports git, hg, bzr, svn and HTTP.
63 | #
64 |
65 | s.source = { :git => "https://github.com/cwRichardKim/RKNotificationHub.git", :tag => s.version.to_s }
66 |
67 |
68 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
69 | #
70 | # CocoaPods is smart about how it includes source code. For source files
71 | # giving a folder will include any h, m, mm, c & cpp files. For header
72 | # files it will include any header in the folder.
73 | # Not including the public_header_files will make all headers public.
74 | #
75 |
76 | s.source_files = 'RKNotificationHub/RKNotificationHub.h', 'RKNotificationHub/RKNotificationHub.m'
77 |
78 | # s.public_header_files = "Classes/**/*.h"
79 |
80 |
81 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
82 | #
83 | # A list of resources included with the Pod. These are copied into the
84 | # target bundle with a build phase script. Anything else will be cleaned.
85 | # You can preserve files from being cleaned, please don't preserve
86 | # non-essential files like tests, examples and documentation.
87 | #
88 |
89 | # s.resource = "icon.png"
90 | # s.resources = "Resources/*.png"
91 |
92 |
93 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
94 | #
95 | # Link your library with frameworks, or libraries. Libraries do not include
96 | # the lib prefix of their name.
97 | #
98 |
99 | # s.framework = "SomeFramework"
100 | # s.frameworks = "SomeFramework", "AnotherFramework"
101 |
102 | # s.library = "iconv"
103 | # s.libraries = "iconv", "xml2"
104 |
105 |
106 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
107 | #
108 | # If your library depends on compiler flags you can set them in the xcconfig hash
109 | # where they will only apply to your library. If you depend on other Podspecs
110 | # you can include multiple dependencies to ensure it works.
111 |
112 | s.requires_arc = true
113 |
114 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
115 | # s.dependency "JSONKit", "~> 1.4"
116 |
117 | end
118 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 998DB1B519DAEA72006655C8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 998DB1B419DAEA72006655C8 /* main.m */; };
11 | 998DB1B819DAEA72006655C8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 998DB1B719DAEA72006655C8 /* AppDelegate.m */; };
12 | 998DB1BB19DAEA72006655C8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 998DB1BA19DAEA72006655C8 /* ViewController.m */; };
13 | 998DB1BE19DAEA72006655C8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 998DB1BC19DAEA72006655C8 /* Main.storyboard */; };
14 | 998DB1C019DAEA72006655C8 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 998DB1BF19DAEA72006655C8 /* Images.xcassets */; };
15 | 998DB1C319DAEA72006655C8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 998DB1C119DAEA72006655C8 /* LaunchScreen.xib */; };
16 | 998DB1CF19DAEA72006655C8 /* RKNotificationHubTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 998DB1CE19DAEA72006655C8 /* RKNotificationHubTests.m */; };
17 | 998DB1DA19DAEE12006655C8 /* RKNotificationHub.m in Sources */ = {isa = PBXBuildFile; fileRef = 998DB1D919DAEE12006655C8 /* RKNotificationHub.m */; };
18 | 998DB1E219DAFE9D006655C8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 998DB1E119DAFE9D006655C8 /* QuartzCore.framework */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | 998DB1C919DAEA72006655C8 /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = 998DB1A719DAEA72006655C8 /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = 998DB1AE19DAEA72006655C8;
27 | remoteInfo = RKNotificationHub;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXFileReference section */
32 | 998DB1AF19DAEA72006655C8 /* RKNotificationHub.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RKNotificationHub.app; sourceTree = BUILT_PRODUCTS_DIR; };
33 | 998DB1B319DAEA72006655C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 998DB1B419DAEA72006655C8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
35 | 998DB1B619DAEA72006655C8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
36 | 998DB1B719DAEA72006655C8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
37 | 998DB1B919DAEA72006655C8 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
38 | 998DB1BA19DAEA72006655C8 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
39 | 998DB1BD19DAEA72006655C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
40 | 998DB1BF19DAEA72006655C8 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
41 | 998DB1C219DAEA72006655C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
42 | 998DB1C819DAEA72006655C8 /* RKNotificationHubTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RKNotificationHubTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 998DB1CD19DAEA72006655C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | 998DB1CE19DAEA72006655C8 /* RKNotificationHubTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RKNotificationHubTests.m; sourceTree = ""; };
45 | 998DB1D819DAEE12006655C8 /* RKNotificationHub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKNotificationHub.h; sourceTree = ""; };
46 | 998DB1D919DAEE12006655C8 /* RKNotificationHub.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKNotificationHub.m; sourceTree = ""; };
47 | 998DB1E119DAFE9D006655C8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
48 | /* End PBXFileReference section */
49 |
50 | /* Begin PBXFrameworksBuildPhase section */
51 | 998DB1AC19DAEA72006655C8 /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | 998DB1E219DAFE9D006655C8 /* QuartzCore.framework in Frameworks */,
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | 998DB1C519DAEA72006655C8 /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXFrameworksBuildPhase section */
67 |
68 | /* Begin PBXGroup section */
69 | 998DB1A619DAEA72006655C8 = {
70 | isa = PBXGroup;
71 | children = (
72 | 998DB1E119DAFE9D006655C8 /* QuartzCore.framework */,
73 | 998DB1B119DAEA72006655C8 /* RKNotificationHub */,
74 | 998DB1CB19DAEA72006655C8 /* RKNotificationHubTests */,
75 | 998DB1B019DAEA72006655C8 /* Products */,
76 | );
77 | sourceTree = "";
78 | };
79 | 998DB1B019DAEA72006655C8 /* Products */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 998DB1AF19DAEA72006655C8 /* RKNotificationHub.app */,
83 | 998DB1C819DAEA72006655C8 /* RKNotificationHubTests.xctest */,
84 | );
85 | name = Products;
86 | sourceTree = "";
87 | };
88 | 998DB1B119DAEA72006655C8 /* RKNotificationHub */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 998DB1B619DAEA72006655C8 /* AppDelegate.h */,
92 | 998DB1B719DAEA72006655C8 /* AppDelegate.m */,
93 | 998DB1B919DAEA72006655C8 /* ViewController.h */,
94 | 998DB1BA19DAEA72006655C8 /* ViewController.m */,
95 | 998DB1D819DAEE12006655C8 /* RKNotificationHub.h */,
96 | 998DB1D919DAEE12006655C8 /* RKNotificationHub.m */,
97 | 998DB1BC19DAEA72006655C8 /* Main.storyboard */,
98 | 998DB1BF19DAEA72006655C8 /* Images.xcassets */,
99 | 998DB1C119DAEA72006655C8 /* LaunchScreen.xib */,
100 | 998DB1B219DAEA72006655C8 /* Supporting Files */,
101 | );
102 | path = RKNotificationHub;
103 | sourceTree = "";
104 | };
105 | 998DB1B219DAEA72006655C8 /* Supporting Files */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 998DB1B319DAEA72006655C8 /* Info.plist */,
109 | 998DB1B419DAEA72006655C8 /* main.m */,
110 | );
111 | name = "Supporting Files";
112 | sourceTree = "";
113 | };
114 | 998DB1CB19DAEA72006655C8 /* RKNotificationHubTests */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 998DB1CE19DAEA72006655C8 /* RKNotificationHubTests.m */,
118 | 998DB1CC19DAEA72006655C8 /* Supporting Files */,
119 | );
120 | path = RKNotificationHubTests;
121 | sourceTree = "";
122 | };
123 | 998DB1CC19DAEA72006655C8 /* Supporting Files */ = {
124 | isa = PBXGroup;
125 | children = (
126 | 998DB1CD19DAEA72006655C8 /* Info.plist */,
127 | );
128 | name = "Supporting Files";
129 | sourceTree = "";
130 | };
131 | /* End PBXGroup section */
132 |
133 | /* Begin PBXNativeTarget section */
134 | 998DB1AE19DAEA72006655C8 /* RKNotificationHub */ = {
135 | isa = PBXNativeTarget;
136 | buildConfigurationList = 998DB1D219DAEA72006655C8 /* Build configuration list for PBXNativeTarget "RKNotificationHub" */;
137 | buildPhases = (
138 | 998DB1AB19DAEA72006655C8 /* Sources */,
139 | 998DB1AC19DAEA72006655C8 /* Frameworks */,
140 | 998DB1AD19DAEA72006655C8 /* Resources */,
141 | );
142 | buildRules = (
143 | );
144 | dependencies = (
145 | );
146 | name = RKNotificationHub;
147 | productName = RKNotificationHub;
148 | productReference = 998DB1AF19DAEA72006655C8 /* RKNotificationHub.app */;
149 | productType = "com.apple.product-type.application";
150 | };
151 | 998DB1C719DAEA72006655C8 /* RKNotificationHubTests */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = 998DB1D519DAEA72006655C8 /* Build configuration list for PBXNativeTarget "RKNotificationHubTests" */;
154 | buildPhases = (
155 | 998DB1C419DAEA72006655C8 /* Sources */,
156 | 998DB1C519DAEA72006655C8 /* Frameworks */,
157 | 998DB1C619DAEA72006655C8 /* Resources */,
158 | );
159 | buildRules = (
160 | );
161 | dependencies = (
162 | 998DB1CA19DAEA72006655C8 /* PBXTargetDependency */,
163 | );
164 | name = RKNotificationHubTests;
165 | productName = RKNotificationHubTests;
166 | productReference = 998DB1C819DAEA72006655C8 /* RKNotificationHubTests.xctest */;
167 | productType = "com.apple.product-type.bundle.unit-test";
168 | };
169 | /* End PBXNativeTarget section */
170 |
171 | /* Begin PBXProject section */
172 | 998DB1A719DAEA72006655C8 /* Project object */ = {
173 | isa = PBXProject;
174 | attributes = {
175 | LastUpgradeCheck = 0600;
176 | ORGANIZATIONNAME = "Richard Kim";
177 | TargetAttributes = {
178 | 998DB1AE19DAEA72006655C8 = {
179 | CreatedOnToolsVersion = 6.0;
180 | };
181 | 998DB1C719DAEA72006655C8 = {
182 | CreatedOnToolsVersion = 6.0;
183 | TestTargetID = 998DB1AE19DAEA72006655C8;
184 | };
185 | };
186 | };
187 | buildConfigurationList = 998DB1AA19DAEA72006655C8 /* Build configuration list for PBXProject "RKNotificationHub" */;
188 | compatibilityVersion = "Xcode 3.2";
189 | developmentRegion = English;
190 | hasScannedForEncodings = 0;
191 | knownRegions = (
192 | en,
193 | Base,
194 | );
195 | mainGroup = 998DB1A619DAEA72006655C8;
196 | productRefGroup = 998DB1B019DAEA72006655C8 /* Products */;
197 | projectDirPath = "";
198 | projectRoot = "";
199 | targets = (
200 | 998DB1AE19DAEA72006655C8 /* RKNotificationHub */,
201 | 998DB1C719DAEA72006655C8 /* RKNotificationHubTests */,
202 | );
203 | };
204 | /* End PBXProject section */
205 |
206 | /* Begin PBXResourcesBuildPhase section */
207 | 998DB1AD19DAEA72006655C8 /* Resources */ = {
208 | isa = PBXResourcesBuildPhase;
209 | buildActionMask = 2147483647;
210 | files = (
211 | 998DB1BE19DAEA72006655C8 /* Main.storyboard in Resources */,
212 | 998DB1C319DAEA72006655C8 /* LaunchScreen.xib in Resources */,
213 | 998DB1C019DAEA72006655C8 /* Images.xcassets in Resources */,
214 | );
215 | runOnlyForDeploymentPostprocessing = 0;
216 | };
217 | 998DB1C619DAEA72006655C8 /* Resources */ = {
218 | isa = PBXResourcesBuildPhase;
219 | buildActionMask = 2147483647;
220 | files = (
221 | );
222 | runOnlyForDeploymentPostprocessing = 0;
223 | };
224 | /* End PBXResourcesBuildPhase section */
225 |
226 | /* Begin PBXSourcesBuildPhase section */
227 | 998DB1AB19DAEA72006655C8 /* Sources */ = {
228 | isa = PBXSourcesBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | 998DB1BB19DAEA72006655C8 /* ViewController.m in Sources */,
232 | 998DB1DA19DAEE12006655C8 /* RKNotificationHub.m in Sources */,
233 | 998DB1B819DAEA72006655C8 /* AppDelegate.m in Sources */,
234 | 998DB1B519DAEA72006655C8 /* main.m in Sources */,
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | 998DB1C419DAEA72006655C8 /* Sources */ = {
239 | isa = PBXSourcesBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | 998DB1CF19DAEA72006655C8 /* RKNotificationHubTests.m in Sources */,
243 | );
244 | runOnlyForDeploymentPostprocessing = 0;
245 | };
246 | /* End PBXSourcesBuildPhase section */
247 |
248 | /* Begin PBXTargetDependency section */
249 | 998DB1CA19DAEA72006655C8 /* PBXTargetDependency */ = {
250 | isa = PBXTargetDependency;
251 | target = 998DB1AE19DAEA72006655C8 /* RKNotificationHub */;
252 | targetProxy = 998DB1C919DAEA72006655C8 /* PBXContainerItemProxy */;
253 | };
254 | /* End PBXTargetDependency section */
255 |
256 | /* Begin PBXVariantGroup section */
257 | 998DB1BC19DAEA72006655C8 /* Main.storyboard */ = {
258 | isa = PBXVariantGroup;
259 | children = (
260 | 998DB1BD19DAEA72006655C8 /* Base */,
261 | );
262 | name = Main.storyboard;
263 | sourceTree = "";
264 | };
265 | 998DB1C119DAEA72006655C8 /* LaunchScreen.xib */ = {
266 | isa = PBXVariantGroup;
267 | children = (
268 | 998DB1C219DAEA72006655C8 /* Base */,
269 | );
270 | name = LaunchScreen.xib;
271 | sourceTree = "";
272 | };
273 | /* End PBXVariantGroup section */
274 |
275 | /* Begin XCBuildConfiguration section */
276 | 998DB1D019DAEA72006655C8 /* Debug */ = {
277 | isa = XCBuildConfiguration;
278 | buildSettings = {
279 | ALWAYS_SEARCH_USER_PATHS = NO;
280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
281 | CLANG_CXX_LIBRARY = "libc++";
282 | CLANG_ENABLE_MODULES = YES;
283 | CLANG_ENABLE_OBJC_ARC = YES;
284 | CLANG_WARN_BOOL_CONVERSION = YES;
285 | CLANG_WARN_CONSTANT_CONVERSION = YES;
286 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
287 | CLANG_WARN_EMPTY_BODY = YES;
288 | CLANG_WARN_ENUM_CONVERSION = YES;
289 | CLANG_WARN_INT_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_UNREACHABLE_CODE = YES;
292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
293 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
294 | COPY_PHASE_STRIP = NO;
295 | ENABLE_STRICT_OBJC_MSGSEND = YES;
296 | GCC_C_LANGUAGE_STANDARD = gnu99;
297 | GCC_DYNAMIC_NO_PIC = NO;
298 | GCC_OPTIMIZATION_LEVEL = 0;
299 | GCC_PREPROCESSOR_DEFINITIONS = (
300 | "DEBUG=1",
301 | "$(inherited)",
302 | );
303 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
304 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
305 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
306 | GCC_WARN_UNDECLARED_SELECTOR = YES;
307 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
308 | GCC_WARN_UNUSED_FUNCTION = YES;
309 | GCC_WARN_UNUSED_VARIABLE = YES;
310 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
311 | MTL_ENABLE_DEBUG_INFO = YES;
312 | ONLY_ACTIVE_ARCH = YES;
313 | SDKROOT = iphoneos;
314 | };
315 | name = Debug;
316 | };
317 | 998DB1D119DAEA72006655C8 /* Release */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ALWAYS_SEARCH_USER_PATHS = NO;
321 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
322 | CLANG_CXX_LIBRARY = "libc++";
323 | CLANG_ENABLE_MODULES = YES;
324 | CLANG_ENABLE_OBJC_ARC = YES;
325 | CLANG_WARN_BOOL_CONVERSION = YES;
326 | CLANG_WARN_CONSTANT_CONVERSION = YES;
327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
328 | CLANG_WARN_EMPTY_BODY = YES;
329 | CLANG_WARN_ENUM_CONVERSION = YES;
330 | CLANG_WARN_INT_CONVERSION = YES;
331 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
332 | CLANG_WARN_UNREACHABLE_CODE = YES;
333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
334 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
335 | COPY_PHASE_STRIP = YES;
336 | ENABLE_NS_ASSERTIONS = NO;
337 | ENABLE_STRICT_OBJC_MSGSEND = YES;
338 | GCC_C_LANGUAGE_STANDARD = gnu99;
339 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
340 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
341 | GCC_WARN_UNDECLARED_SELECTOR = YES;
342 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
343 | GCC_WARN_UNUSED_FUNCTION = YES;
344 | GCC_WARN_UNUSED_VARIABLE = YES;
345 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
346 | MTL_ENABLE_DEBUG_INFO = NO;
347 | SDKROOT = iphoneos;
348 | VALIDATE_PRODUCT = YES;
349 | };
350 | name = Release;
351 | };
352 | 998DB1D319DAEA72006655C8 /* Debug */ = {
353 | isa = XCBuildConfiguration;
354 | buildSettings = {
355 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
356 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
357 | INFOPLIST_FILE = RKNotificationHub/Info.plist;
358 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
359 | PRODUCT_NAME = "$(TARGET_NAME)";
360 | };
361 | name = Debug;
362 | };
363 | 998DB1D419DAEA72006655C8 /* Release */ = {
364 | isa = XCBuildConfiguration;
365 | buildSettings = {
366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
367 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
368 | INFOPLIST_FILE = RKNotificationHub/Info.plist;
369 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | };
372 | name = Release;
373 | };
374 | 998DB1D619DAEA72006655C8 /* Debug */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | BUNDLE_LOADER = "$(TEST_HOST)";
378 | FRAMEWORK_SEARCH_PATHS = (
379 | "$(SDKROOT)/Developer/Library/Frameworks",
380 | "$(inherited)",
381 | );
382 | GCC_PREPROCESSOR_DEFINITIONS = (
383 | "DEBUG=1",
384 | "$(inherited)",
385 | );
386 | INFOPLIST_FILE = RKNotificationHubTests/Info.plist;
387 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
388 | PRODUCT_NAME = "$(TARGET_NAME)";
389 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RKNotificationHub.app/RKNotificationHub";
390 | };
391 | name = Debug;
392 | };
393 | 998DB1D719DAEA72006655C8 /* Release */ = {
394 | isa = XCBuildConfiguration;
395 | buildSettings = {
396 | BUNDLE_LOADER = "$(TEST_HOST)";
397 | FRAMEWORK_SEARCH_PATHS = (
398 | "$(SDKROOT)/Developer/Library/Frameworks",
399 | "$(inherited)",
400 | );
401 | INFOPLIST_FILE = RKNotificationHubTests/Info.plist;
402 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
403 | PRODUCT_NAME = "$(TARGET_NAME)";
404 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RKNotificationHub.app/RKNotificationHub";
405 | };
406 | name = Release;
407 | };
408 | /* End XCBuildConfiguration section */
409 |
410 | /* Begin XCConfigurationList section */
411 | 998DB1AA19DAEA72006655C8 /* Build configuration list for PBXProject "RKNotificationHub" */ = {
412 | isa = XCConfigurationList;
413 | buildConfigurations = (
414 | 998DB1D019DAEA72006655C8 /* Debug */,
415 | 998DB1D119DAEA72006655C8 /* Release */,
416 | );
417 | defaultConfigurationIsVisible = 0;
418 | defaultConfigurationName = Release;
419 | };
420 | 998DB1D219DAEA72006655C8 /* Build configuration list for PBXNativeTarget "RKNotificationHub" */ = {
421 | isa = XCConfigurationList;
422 | buildConfigurations = (
423 | 998DB1D319DAEA72006655C8 /* Debug */,
424 | 998DB1D419DAEA72006655C8 /* Release */,
425 | );
426 | defaultConfigurationIsVisible = 0;
427 | defaultConfigurationName = Release;
428 | };
429 | 998DB1D519DAEA72006655C8 /* Build configuration list for PBXNativeTarget "RKNotificationHubTests" */ = {
430 | isa = XCConfigurationList;
431 | buildConfigurations = (
432 | 998DB1D619DAEA72006655C8 /* Debug */,
433 | 998DB1D719DAEA72006655C8 /* Release */,
434 | );
435 | defaultConfigurationIsVisible = 0;
436 | defaultConfigurationName = Release;
437 | };
438 | /* End XCConfigurationList section */
439 | };
440 | rootObject = 998DB1A719DAEA72006655C8 /* Project object */;
441 | }
442 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/project.xcworkspace/xcshareddata/RKNotificationHub.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | B8D09011-1D77-4809-B086-095EB7183CB0
9 | IDESourceControlProjectName
10 | RKNotificationHub
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 520F45C700A540DF04AC14D3D535CA39508D941F
14 | https://github.com/cwRichardKim/RKNotificationHub.git
15 |
16 | IDESourceControlProjectPath
17 | RKNotificationHub.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 520F45C700A540DF04AC14D3D535CA39508D941F
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/cwRichardKim/RKNotificationHub.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 520F45C700A540DF04AC14D3D535CA39508D941F
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 520F45C700A540DF04AC14D3D535CA39508D941F
36 | IDESourceControlWCCName
37 | RKNotificationHub
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/project.xcworkspace/xcuserdata/cwrichardkim93.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cwRichardKim/RKNotificationHub/b6592f1226774dbeededbf03ea8cc26827881315/RKNotificationHub.xcodeproj/project.xcworkspace/xcuserdata/cwrichardkim93.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/xcuserdata/cwrichardkim93.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/xcuserdata/cwrichardkim93.xcuserdatad/xcschemes/RKNotificationHub.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/RKNotificationHub.xcodeproj/xcuserdata/cwrichardkim93.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | RKNotificationHub.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 998DB1AE19DAEA72006655C8
16 |
17 | primary
18 |
19 |
20 | 998DB1C719DAEA72006655C8
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/RKNotificationHub/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | /* Credits: Earth Icon made by http://www.icomoon.io */
10 |
11 | #import
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 |
18 | @end
19 |
20 |
--------------------------------------------------------------------------------
/RKNotificationHub/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
18 | return YES;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/RKNotificationHub/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/RKNotificationHub/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "minimum-system-version" : "7.0",
7 | "scale" : "2x"
8 | },
9 | {
10 | "orientation" : "portrait",
11 | "idiom" : "iphone",
12 | "minimum-system-version" : "7.0",
13 | "subtype" : "retina4",
14 | "scale" : "2x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/earth.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "earth.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "earth-1.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "earth-1-1.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/earth.imageset/earth-1-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cwRichardKim/RKNotificationHub/b6592f1226774dbeededbf03ea8cc26827881315/RKNotificationHub/Images.xcassets/earth.imageset/earth-1-1.png
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/earth.imageset/earth-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cwRichardKim/RKNotificationHub/b6592f1226774dbeededbf03ea8cc26827881315/RKNotificationHub/Images.xcassets/earth.imageset/earth-1.png
--------------------------------------------------------------------------------
/RKNotificationHub/Images.xcassets/earth.imageset/earth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cwRichardKim/RKNotificationHub/b6592f1226774dbeededbf03ea8cc26827881315/RKNotificationHub/Images.xcassets/earth.imageset/earth.png
--------------------------------------------------------------------------------
/RKNotificationHub/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.cwRichardKim.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/RKNotificationHub/RKNotificationHub.h:
--------------------------------------------------------------------------------
1 | //
2 | // RKNotificationHub.h
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | /*
10 |
11 | Copyright (c) 2014 Choong-Won Richard Kim
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is furnished
18 | to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in all
21 | copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 | THE SOFTWARE.
30 |
31 | */
32 |
33 |
34 | #import
35 | #import
36 |
37 | /**
38 | * The default diameter of the notification hub view.
39 | */
40 | FOUNDATION_EXPORT CGFloat const RKNotificationHubDefaultDiameter;
41 |
42 | @interface RKNotificationHub : NSObject
43 |
44 | //%%% setup
45 | - (id)initWithView:(UIView *)view;
46 | - (id)initWithBarButtonItem:(UIBarButtonItem *)barButtonItem;
47 |
48 | //%%% adjustment methods
49 | - (void)setView:(UIView *)view andCount:(int)startCount;
50 | - (void)setCircleAtFrame:(CGRect)frame;
51 | - (void)setCircleColor:(UIColor*)circleColor labelColor:(UIColor*)labelColor;
52 | - (void)setCircleBorderColor:(UIColor *)color borderWidth:(CGFloat)width;
53 | - (void)moveCircleByX:(CGFloat)x Y:(CGFloat)y;
54 | - (void)scaleCircleSizeBy:(CGFloat)scale;
55 | @property (nonatomic, strong) UIFont *countLabelFont;
56 |
57 | //%%% changing the count
58 | - (void)increment;
59 | - (void)incrementBy:(int)amount;
60 | - (void)decrement;
61 | - (void)decrementBy:(int)amount;
62 | @property (nonatomic, assign) int count;
63 | @property (nonatomic, assign) int maxCount;
64 |
65 | //%%% hiding / showing the count
66 | - (void)hideCount;
67 | - (void)showCount;
68 |
69 | //%%% animations
70 | - (void)pop;
71 | - (void)blink;
72 | - (void)bump;
73 |
74 | @property (nonatomic)UIView *hubView;
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/RKNotificationHub/RKNotificationHub.m:
--------------------------------------------------------------------------------
1 | //
2 | // RKNotificationHub.m
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | #import "RKNotificationHub.h"
10 | #import
11 |
12 | //%%% default diameter
13 | CGFloat const RKNotificationHubDefaultDiameter = 30;
14 | static CGFloat const kCountMagnitudeAdaptationRatio = 0.3;
15 | //%%% pop values
16 | static CGFloat const kPopStartRatio = .85;
17 | static CGFloat const kPopOutRatio = 1.05;
18 | static CGFloat const kPopInRatio = .95;
19 |
20 | //%%% blink values
21 | static CGFloat const kBlinkDuration = 0.1;
22 | static CGFloat const kBlinkAlpha = 0.1;
23 |
24 | //%%% bump values
25 | static CGFloat const kFirstBumpDistance = 8.0;
26 | static CGFloat const kBumpTimeSeconds = 0.13;
27 | static CGFloat const SECOND_BUMP_DIST = 4.0;
28 | static CGFloat const kBumpTimeSeconds2 = 0.1;
29 |
30 | @interface RKView : UIView
31 | @property (nonatomic) BOOL isUserChangingBackgroundColor;
32 | @end
33 |
34 | @implementation RKView
35 |
36 | - (void)setBackgroundColor:(UIColor *)backgroundColor
37 | {
38 | if (self.isUserChangingBackgroundColor) {
39 | super.backgroundColor = backgroundColor;
40 | self.isUserChangingBackgroundColor = NO;
41 | }
42 | }
43 |
44 | @end
45 |
46 |
47 | @implementation RKNotificationHub {
48 | int curOrderMagnitude;
49 | UILabel *countLabel;
50 | RKView *redCircle;
51 | CGPoint initialCenter;
52 | CGRect baseFrame;
53 | CGRect initialFrame;
54 | BOOL isIndeterminateMode;
55 | }
56 |
57 | @synthesize hubView;
58 |
59 | #pragma mark - SETUP
60 |
61 | - (id)initWithView:(UIView *)view
62 | {
63 | self = [super init];
64 | if (!self) return nil;
65 |
66 | _maxCount = 100000;
67 | [self setView:view andCount:0];
68 |
69 | return self;
70 | }
71 |
72 | - (id)initWithBarButtonItem:(UIBarButtonItem *)barButtonItem
73 | {
74 | self = [self initWithView:[barButtonItem valueForKey:@"view"]];
75 | [self scaleCircleSizeBy:0.7];
76 | [self moveCircleByX:-5.0 Y:0];
77 |
78 | return self;
79 | }
80 |
81 | //%%% give this a view and an initial count (0 hides the notification circle)
82 | // and it will make a hub for you
83 | - (void)setView:(UIView *)view andCount:(int)startCount
84 | {
85 | curOrderMagnitude = 0;
86 |
87 | CGRect frame = view.frame;
88 |
89 | isIndeterminateMode = NO;
90 |
91 | redCircle = [[RKView alloc]init];
92 | redCircle.userInteractionEnabled = NO;
93 | redCircle.isUserChangingBackgroundColor = YES;
94 | redCircle.backgroundColor = [UIColor redColor];
95 |
96 | countLabel = [[UILabel alloc]initWithFrame:redCircle.frame];
97 | countLabel.userInteractionEnabled = NO;
98 | self.count = startCount;
99 | [countLabel setTextAlignment:NSTextAlignmentCenter];
100 | countLabel.textColor = [UIColor whiteColor];
101 | countLabel.backgroundColor = [UIColor clearColor];
102 |
103 | [self setCircleAtFrame:CGRectMake(frame.size.width- (RKNotificationHubDefaultDiameter*2/3), -RKNotificationHubDefaultDiameter/3, RKNotificationHubDefaultDiameter, RKNotificationHubDefaultDiameter)];
104 |
105 | [view addSubview:redCircle];
106 | [view addSubview:countLabel];
107 | [view bringSubviewToFront:redCircle];
108 | [view bringSubviewToFront:countLabel];
109 | hubView = view;
110 | [self checkZero];
111 | }
112 |
113 | //%%% set the frame of the notification circle relative to the button
114 | - (void)setCircleAtFrame:(CGRect)frame
115 | {
116 | [redCircle setFrame:frame];
117 | initialCenter = CGPointMake(frame.origin.x+frame.size.width/2, frame.origin.y+frame.size.height/2);
118 | baseFrame = frame;
119 | initialFrame = frame;
120 | countLabel.frame = redCircle.frame;
121 | redCircle.layer.cornerRadius = frame.size.height/2;
122 | [countLabel setFont:[UIFont fontWithName:@"HelveticaNeue" size:frame.size.width/2]];
123 | [self expandToFitLargerDigits];
124 | }
125 |
126 | //%%% moves the circle by x amount on the x axis and y amount on the y axis
127 | - (void)moveCircleByX:(CGFloat)x Y:(CGFloat)y
128 | {
129 | CGRect frame = redCircle.frame;
130 | frame.origin.x += x;
131 | frame.origin.y += y;
132 | [self setCircleAtFrame:frame];
133 | }
134 |
135 | //%%% changes the size of the circle. setting a scale of 1 has no effect
136 | - (void)scaleCircleSizeBy:(CGFloat)scale
137 | {
138 | CGRect fr = initialFrame;
139 | CGFloat width = fr.size.width * scale;
140 | CGFloat height = fr.size.height * scale;
141 | CGFloat wdiff = (fr.size.width - width) / 2;
142 | CGFloat hdiff = (fr.size.height - height) / 2;
143 |
144 | CGRect frame = CGRectMake(fr.origin.x + wdiff, fr.origin.y + hdiff, width, height);
145 | [self setCircleAtFrame:frame];
146 | }
147 |
148 | //%%% change the color of the notification circle
149 | - (void)setCircleColor:(UIColor*)circleColor labelColor:(UIColor*)labelColor
150 | {
151 | redCircle.isUserChangingBackgroundColor = YES;
152 | redCircle.backgroundColor = circleColor;
153 | [countLabel setTextColor:labelColor];
154 | }
155 |
156 | - (void)setCircleBorderColor:(UIColor *)color borderWidth:(CGFloat)width {
157 | redCircle.layer.borderColor = color.CGColor;
158 | redCircle.layer.borderWidth = width;
159 | }
160 |
161 | - (void)hideCount
162 | {
163 | countLabel.hidden = YES;
164 | isIndeterminateMode = YES;
165 | }
166 |
167 | - (void)showCount
168 | {
169 | isIndeterminateMode = NO;
170 | [self checkZero];
171 | }
172 |
173 | #pragma mark - ATTRIBUTES
174 |
175 | //%%% increases count by 1
176 | - (void)increment
177 | {
178 | [self incrementBy:1];
179 | }
180 |
181 | //%%% increases count by amount
182 | - (void)incrementBy:(int)amount
183 | {
184 | self.count += amount;
185 | }
186 |
187 | //%%% decreases count
188 | - (void)decrement
189 | {
190 | [self decrementBy:1];
191 | }
192 |
193 | //%%% decreases count by amount
194 | - (void)decrementBy:(int)amount
195 | {
196 | if (amount >= self.count) {
197 | self.count = 0;
198 | return;
199 | }
200 | self.count -= amount;
201 | }
202 |
203 | //%%% set the count yourself
204 | - (void)setCount:(int)newCount
205 | {
206 | _count = newCount;
207 |
208 | NSString *labelText = [NSString stringWithFormat:@"%@", @(self.count)];
209 |
210 | if (_count > self.maxCount){
211 | labelText = [NSString stringWithFormat:@"%@+", @(self.maxCount)];
212 | }
213 |
214 | countLabel.text = labelText;
215 | [self checkZero];
216 | [self expandToFitLargerDigits];
217 | }
218 |
219 | //%% set the font of the label
220 | - (void)setCountLabelFont:(UIFont *)font
221 | {
222 | [countLabel setFont:font];
223 | }
224 |
225 | - (UIFont *)countLabelFont
226 | {
227 | return countLabel.font;
228 | }
229 |
230 | #pragma mark - ANIMATION
231 |
232 | //%%% animation that resembles facebook's pop
233 | - (void)pop
234 | {
235 | const float height = baseFrame.size.height;
236 | const float width = baseFrame.size.width;
237 | const float pop_start_h = height * kPopStartRatio;
238 | const float pop_start_w = width * kPopStartRatio;
239 | const float time_start = 0.05;
240 | const float pop_out_h = height * kPopOutRatio;
241 | const float pop_out_w = width * kPopOutRatio;
242 | const float time_out = .2;
243 | const float pop_in_h = height * kPopInRatio;
244 | const float pop_in_w = width * kPopInRatio;
245 | const float time_in = .05;
246 | const float pop_end_h = height;
247 | const float pop_end_w = width;
248 | const float time_end = 0.05;
249 |
250 | CABasicAnimation *startSize = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
251 | startSize.duration = time_start;
252 | startSize.beginTime = 0;
253 | startSize.fromValue = @(pop_end_h / 2);
254 | startSize.toValue = @(pop_start_h / 2);
255 | startSize.removedOnCompletion = FALSE;
256 |
257 | CABasicAnimation *outSize = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
258 | outSize.duration = time_out;
259 | outSize.beginTime = time_start;
260 | outSize.fromValue = startSize.toValue;
261 | outSize.toValue = @(pop_out_h / 2);
262 | outSize.removedOnCompletion = FALSE;
263 |
264 | CABasicAnimation *inSize = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
265 | inSize.duration = time_in;
266 | inSize.beginTime = time_start+time_out;
267 | inSize.fromValue = outSize.toValue;
268 | inSize.toValue = @(pop_in_h / 2);
269 | inSize.removedOnCompletion = FALSE;
270 |
271 | CABasicAnimation *endSize = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
272 | endSize.duration = time_end;
273 | endSize.beginTime = time_in+time_out+time_start;
274 | endSize.fromValue = inSize.toValue;
275 | endSize.toValue = @(pop_end_h / 2);
276 | endSize.removedOnCompletion = FALSE;
277 |
278 | CAAnimationGroup *group = [CAAnimationGroup animation];
279 | [group setDuration: time_start+time_out+time_in+time_end];
280 | [group setAnimations:@[startSize, outSize, inSize, endSize]];
281 |
282 | [redCircle.layer addAnimation:group forKey:nil];
283 |
284 | [UIView animateWithDuration:time_start animations:^{
285 | CGRect frame = redCircle.frame;
286 | CGPoint center = redCircle.center;
287 | frame.size.height = pop_start_h;
288 | frame.size.width = pop_start_w;
289 | redCircle.frame = frame;
290 | redCircle.center = center;
291 | }completion:^(BOOL complete){
292 | [UIView animateWithDuration:time_out animations:^{
293 | CGRect frame = redCircle.frame;
294 | CGPoint center = redCircle.center;
295 | frame.size.height = pop_out_h;
296 | frame.size.width = pop_out_w;
297 | redCircle.frame = frame;
298 | redCircle.center = center;
299 | }completion:^(BOOL complete){
300 | [UIView animateWithDuration:time_in animations:^{
301 | CGRect frame = redCircle.frame;
302 | CGPoint center = redCircle.center;
303 | frame.size.height = pop_in_h;
304 | frame.size.width = pop_in_w;
305 | redCircle.frame = frame;
306 | redCircle.center = center;
307 | }completion:^(BOOL complete){
308 | [UIView animateWithDuration:time_end animations:^{
309 | CGRect frame = redCircle.frame;
310 | CGPoint center = redCircle.center;
311 | frame.size.height = pop_end_h;
312 | frame.size.width = pop_end_w;
313 | redCircle.frame = frame;
314 | redCircle.center = center;
315 | }];
316 | }];
317 | }];
318 | }];
319 | }
320 |
321 | //%%% animation that flashes on an off
322 | - (void)blink
323 | {
324 | [self setAlpha:kBlinkAlpha];
325 |
326 | [UIView animateWithDuration:kBlinkDuration animations:^{
327 | [self setAlpha:1];
328 | }completion:^(BOOL complete){
329 | [UIView animateWithDuration:kBlinkDuration animations:^{
330 | [self setAlpha:kBlinkAlpha];
331 | }completion:^(BOOL complete){
332 | [UIView animateWithDuration:kBlinkDuration animations:^{
333 | [self setAlpha:1];
334 | }];
335 | }];
336 | }];
337 | }
338 |
339 | //%%% animation that jumps similar to OSX dock icons
340 | - (void)bump
341 | {
342 | if (!CGPointEqualToPoint(initialCenter,redCircle.center)) {
343 | //%%% canel previous animation
344 | }
345 |
346 | [self bumpCenterY:0];
347 | [UIView animateWithDuration:kBumpTimeSeconds animations:^{
348 | [self bumpCenterY:kFirstBumpDistance];
349 | }completion:^(BOOL complete){
350 | [UIView animateWithDuration:kBumpTimeSeconds animations:^{
351 | [self bumpCenterY:0];
352 | }completion:^(BOOL complete){
353 | [UIView animateWithDuration:kBumpTimeSeconds2 animations:^{
354 | [self bumpCenterY:SECOND_BUMP_DIST];
355 | }completion:^(BOOL complete){
356 | [UIView animateWithDuration:kBumpTimeSeconds2 animations:^{
357 | [self bumpCenterY:0];
358 | }];
359 | }];
360 | }];
361 | }];
362 | }
363 |
364 | #pragma mark - HELPERS
365 |
366 | //%%% changes the Y origin of the notification circle
367 | - (void)bumpCenterY:(float)yVal
368 | {
369 | CGPoint center = redCircle.center;
370 | center.y = initialCenter.y-yVal;
371 | redCircle.center = center;
372 | countLabel.center = center;
373 | }
374 |
375 | - (void)setAlpha:(float)alpha
376 | {
377 | redCircle.alpha = alpha;
378 | countLabel.alpha = alpha;
379 | }
380 |
381 | //%%% hides the notification if the value is 0
382 | - (void)checkZero
383 | {
384 | if (self.count <= 0) {
385 | redCircle.hidden = YES;
386 | countLabel.hidden = YES;
387 | } else {
388 | redCircle.hidden = NO;
389 | if (!isIndeterminateMode) {
390 | countLabel.hidden = NO;
391 | }
392 | }
393 | }
394 |
395 | - (void)expandToFitLargerDigits {
396 | int orderOfMagnitude = log10((double)self.count);
397 | orderOfMagnitude = (orderOfMagnitude >= 2) ? orderOfMagnitude : 1;
398 | CGRect frame = initialFrame;
399 | frame.size.width = initialFrame.size.width * (1 + kCountMagnitudeAdaptationRatio * (orderOfMagnitude - 1));
400 | frame.origin.x = initialFrame.origin.x - (frame.size.width - initialFrame.size.width) / 2;
401 |
402 | [redCircle setFrame:frame];
403 | initialCenter = CGPointMake(frame.origin.x+frame.size.width/2, frame.origin.y+frame.size.height/2);
404 | baseFrame = frame;
405 | countLabel.frame = redCircle.frame;
406 | curOrderMagnitude = orderOfMagnitude;
407 | }
408 |
409 | @end
410 |
--------------------------------------------------------------------------------
/RKNotificationHub/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | /*
10 |
11 | Copyright (c) 2014 Choong-Won Richard Kim
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy
14 | of this software and associated documentation files (the "Software"), to deal
15 | in the Software without restriction, including without limitation the rights
16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 | copies of the Software, and to permit persons to whom the Software is furnished
18 | to do so, subject to the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included in all
21 | copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 | THE SOFTWARE.
30 |
31 | */
32 |
33 |
34 | #import
35 |
36 | @interface ViewController : UIViewController
37 |
38 | - (IBAction)barButtonPressed:(id)sender;
39 |
40 | @end
41 |
42 |
--------------------------------------------------------------------------------
/RKNotificationHub/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "RKNotificationHub.h"
11 |
12 | @interface ViewController () {
13 | RKNotificationHub *hub;
14 | RKNotificationHub *barHub;
15 | }
16 | @property (weak, nonatomic) IBOutlet UIBarButtonItem *barButtonItem;
17 |
18 | @end
19 |
20 | @implementation ViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 | [self setupButton];
25 |
26 | UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"earth"]];
27 | imageView.frame = CGRectMake(self.view.frame.size.width/2 - 35, 120, 70, 70);
28 |
29 | hub = [[RKNotificationHub alloc]initWithView:imageView];
30 | [hub moveCircleByX:-5 Y:5]; // moves the circle five pixels left and 5 down
31 | // [hub hideCount]; // uncomment for a blank badge
32 |
33 | barHub = [[RKNotificationHub alloc] initWithBarButtonItem: _barButtonItem];
34 | [barHub increment];
35 |
36 | [self.view addSubview:imageView];
37 | }
38 |
39 |
40 | - (IBAction)barButtonPressed:(id)sender {
41 | [barHub increment];
42 | [barHub pop];
43 | }
44 |
45 | -(void)testIncrement
46 | {
47 | [hub increment];
48 |
49 | [hub pop];
50 | // [hub blink];
51 | // [hub bump];
52 | }
53 |
54 | // (ignore this, for personal stress testing purposes)
55 | - (void)stressTest {
56 | [hub setCount:pow(10, arc4random_uniform(5))];
57 | int rand = arc4random_uniform(7);
58 | switch (rand)
59 | {
60 | case 0:
61 | [hub scaleCircleSizeBy: 1.2];
62 | break;
63 | case 1:
64 | [hub scaleCircleSizeBy: .833];
65 | break;
66 | default:
67 | break;
68 | }
69 | rand = arc4random_uniform(4);
70 | switch (rand)
71 | {
72 | case 0:
73 | [hub pop];
74 | break;
75 | case 1:
76 | [hub blink];
77 | break;
78 | case 2:
79 | [hub bump];
80 | break;
81 | default:
82 | break;
83 | }
84 | }
85 |
86 | -(void)setupButton
87 | {
88 | UIColor* color = [UIColor colorWithRed:.15 green:.67 blue:.88 alpha:1];
89 |
90 | UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(50, 400, 200, 60)];
91 | button.center = self.view.center;
92 | [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
93 | [button setTitle:@"Increment" forState:UIControlStateNormal];
94 | [button setBackgroundColor:color];
95 | button.layer.cornerRadius = 5;
96 | [button addTarget:self action:@selector(testIncrement) forControlEvents:UIControlEventTouchUpInside];
97 |
98 | [self.view addSubview:button];
99 | }
100 |
101 | - (void)didReceiveMemoryWarning {
102 | [super didReceiveMemoryWarning];
103 | // Dispose of any resources that can be recreated.
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/RKNotificationHub/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // RKNotificationHub
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/RKNotificationHubTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.cwRichardKim.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/RKNotificationHubTests/RKNotificationHubTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RKNotificationHubTests.m
3 | // RKNotificationHubTests
4 | //
5 | // Created by Richard Kim on 9/30/14.
6 | // Copyright (c) 2014 Richard Kim. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface RKNotificationHubTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation RKNotificationHubTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------