├── screens
├── demo.gif
└── screen0.png
├── Example Project
├── ExampleProject
│ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ ├── ViewController_iPad.xib
│ │ └── ViewController_iPhone.xib
│ ├── ModalViewController.h
│ ├── ExampleProject-Prefix.pch
│ ├── main.m
│ ├── AppDelegate.h
│ ├── ViewController.h
│ ├── ModalViewController.m
│ ├── ExampleProject-Info.plist
│ ├── AppDelegate.m
│ ├── ViewController.m
│ ├── ModalViewController_iPhone.xib
│ └── ModalViewController_iPad.xib
├── ShakingAlertViewKiwiTest
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── ShakingAlertViewKiwiTest-Prefix.pch
│ ├── ShakingAlertViewKiwiTest-Info.plist
│ └── ShakingAlertViewTests.m
├── Podfile
├── Default-568h@2x.png
├── Podfile.lock
├── ExampleProject.xcworkspace
│ └── contents.xcworkspacedata
└── ExampleProject.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ ├── xcuserdata
│ └── luke.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ ├── xcshareddata
│ └── xcschemes
│ │ ├── ShakingAlertViewKiwiTest.xcscheme
│ │ └── ShakingAlertView.xcscheme
│ └── project.pbxproj
├── .gitignore
├── .travis.yml
├── src
├── b64.h
├── NSData+Base64.h
├── NSData+Base64.m
├── ShakingAlertView.h
├── b64.m
└── ShakingAlertView.m
├── ShakingAlertView.podspec
├── License.txt
└── README.md
/screens/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukestringer90/ShakingAlertView/HEAD/screens/demo.gif
--------------------------------------------------------------------------------
/screens/screen0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukestringer90/ShakingAlertView/HEAD/screens/screen0.png
--------------------------------------------------------------------------------
/Example Project/ExampleProject/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example Project/ShakingAlertViewKiwiTest/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example Project/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios
2 | target :ShakingAlertViewKiwiTest, :exclusive => true do
3 | pod 'Kiwi'
4 | end
--------------------------------------------------------------------------------
/Example Project/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lukestringer90/ShakingAlertView/HEAD/Example Project/Default-568h@2x.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.xcodeproj/project.xcworkspace/*
3 |
4 | Example Project/Pods/*
5 | *.xcuserstate
6 | *.xcsettings
7 | *.xcbkptlist
8 |
--------------------------------------------------------------------------------
/Example Project/Podfile.lock:
--------------------------------------------------------------------------------
1 |
2 | COCOAPODS: 0.16.1
3 |
4 | PODS:
5 | - Kiwi (2.0.4)
6 |
7 | DEPENDENCIES:
8 | - Kiwi
9 |
10 | SPEC CHECKSUMS:
11 | Kiwi: 44abe10fc11eb6a9e05d580211abd1f8fdb01260
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | before_install:
3 | - brew update
4 | - brew install xctool
5 | - cd Example\ Project
6 | - pod install
7 | script: xctool test -project ExampleProject.xcodeproj/ -scheme ShakingAlertView
8 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example Project/ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'ShakingAlertViewKiwiTest' target in the 'ShakingAlertViewKiwiTest' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import
8 | #endif
9 |
--------------------------------------------------------------------------------
/src/b64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * b64.h
3 | * AQToolkit
4 | *
5 | * Created by Jim Dovey on 11-01-11.
6 | * Based on b64.c by Bob Trower
7 | *
8 | *
9 | */
10 |
11 | #import
12 |
13 | NSData * b64_encode( NSData * data );
14 | NSData * b64_decode( NSData * data );
15 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ModalViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ModalViewController.h
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 21/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ModalViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ExampleProject-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'ShakingAlertView' target in the 'ShakingAlertView' 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 | #endif
15 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 23/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. 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 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 23/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ViewController;
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @property (strong, nonatomic) ViewController *viewController;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 21/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ShakingAlertView.h"
11 |
12 |
13 | @interface ViewController : UIViewController
14 |
15 | - (IBAction)plainTextLoginTapped:(id)sender;
16 | - (IBAction)sha1LoginTapped:(id)sender;
17 | - (IBAction)md5LoginTaped:(id)sender;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Example Project/ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | com.lukestringer.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcodeproj/xcuserdata/luke.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ShakingAlertView.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | ShakingAlertViewKiwiTest.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 1
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | A33909CB160F17D80083C023
21 |
22 | primary
23 |
24 |
25 | A3F40CCD16D189F900E5FA63
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ShakingAlertView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "ShakingAlertView"
3 | s.version = "1.0.0"
4 | s.summary = "UIAlertView subclass containing a password entry field and a 'shake' animation for incorrect password entry."
5 | s.description = "ShakingAlertView is a UIAlertView subclass with a password entry textfield. Incorrect password entry causes a 'shake' animation similar to the OS X account login screen."
6 | s.homepage = "https://github.com/stringer630/ShakingAlertView"
7 | s.screenshots = "https://raw.github.com/stringer630/ShakingAlertView/master/screens/screen0.png"
8 | s.license = { :type => 'MIT', :file => 'License.txt' }
9 | s.author = { "Luke Stringer" => "luke.stringer@me.com" }
10 | s.source = { :git => "https://github.com/stringer630/ShakingAlertView.git", :tag => "1.0.0" }
11 | s.ios.deployment_target = '5.0'
12 | s.source_files = 'src'
13 | s.requires_arc = true
14 | end
15 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 | This code is distributed under the terms and conditions of the MIT license.
2 |
3 | Copyright (c) 2012 Luke Stringer
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ModalViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ModalViewController.m
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 21/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import "ModalViewController.h"
10 |
11 |
12 |
13 | @implementation ModalViewController
14 |
15 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
16 | {
17 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
18 | if (self) {
19 | // Custom initialization
20 | }
21 | return self;
22 | }
23 |
24 | - (void)viewDidLoad
25 | {
26 | [super viewDidLoad];
27 | // Do any additional setup after loading the view from its nib.
28 |
29 | self.title = @"Password Protected";
30 |
31 | UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(dismissModalViewControllerAnimated:)];
32 | self.navigationItem.rightBarButtonItem = doneButton;
33 | }
34 |
35 | - (void)viewDidUnload
36 | {
37 | [super viewDidUnload];
38 | // Release any retained subviews of the main view.
39 | // e.g. self.myOutlet = nil;
40 | }
41 |
42 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
43 | {
44 | return (interfaceOrientation == UIInterfaceOrientationPortrait);
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ExampleProject-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.lukestringer.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/NSData+Base64.h:
--------------------------------------------------------------------------------
1 | /*
2 | * NSData+Base64.h
3 | * AQToolkit
4 | *
5 | * Created by Jim Dovey on 31/8/2008.
6 | *
7 | * Copyright (c) 2008-2009, Jim Dovey
8 | * All rights reserved.
9 | *
10 | * Redistribution and use in source and binary forms, with or without
11 | * modification, are permitted provided that the following conditions
12 | * are met:
13 | *
14 | * Redistributions of source code must retain the above copyright notice,
15 | * this list of conditions and the following disclaimer.
16 | *
17 | * Redistributions in binary form must reproduce the above copyright
18 | * notice, this list of conditions and the following disclaimer in the
19 | * documentation and/or other materials provided with the distribution.
20 | *
21 | * Neither the name of this project's author nor the names of its
22 | * contributors may be used to endorse or promote products derived from
23 | * this software without specific prior written permission.
24 | *
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 | *
37 | */
38 |
39 | #import
40 |
41 | @class NSString;
42 |
43 | @interface NSData (Base64)
44 |
45 | + (NSData *) dataFromBase64String: (NSString *) base64String;
46 | - (id) initWithBase64String: (NSString *) base64String;
47 | - (NSString *) base64EncodedString;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcodeproj/xcshareddata/xcschemes/ShakingAlertViewKiwiTest.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
36 |
37 |
38 |
39 |
45 |
46 |
48 |
49 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/NSData+Base64.m:
--------------------------------------------------------------------------------
1 | /*
2 | * NSData+Base64.h
3 | * AQToolkit
4 | *
5 | * Created by Jim Dovey on 31/8/2008.
6 | *
7 | * Copyright (c) 2008-2009, Jim Dovey
8 | * All rights reserved.
9 | *
10 | * Redistribution and use in source and binary forms, with or without
11 | * modification, are permitted provided that the following conditions
12 | * are met:
13 | *
14 | * Redistributions of source code must retain the above copyright notice,
15 | * this list of conditions and the following disclaimer.
16 | *
17 | * Redistributions in binary form must reproduce the above copyright
18 | * notice, this list of conditions and the following disclaimer in the
19 | * documentation and/or other materials provided with the distribution.
20 | *
21 | * Neither the name of this project's author nor the names of its
22 | * contributors may be used to endorse or promote products derived from
23 | * this software without specific prior written permission.
24 | *
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 | *
37 | */
38 |
39 | #import
40 | #import "NSData+Base64.h"
41 | #import "b64.h"
42 |
43 | @implementation NSData (Base64)
44 |
45 | + (NSData *) dataFromBase64String: (NSString *) base64String
46 | {
47 | NSData * charData = [base64String dataUsingEncoding: NSUTF8StringEncoding];
48 | return ( b64_decode(charData) );
49 | }
50 |
51 | - (id) initWithBase64String: (NSString *) base64String
52 | {
53 | NSData * charData = [base64String dataUsingEncoding: NSUTF8StringEncoding];
54 | NSData * result = b64_decode(charData); // we'll return this with 1 extant retain count
55 | return ( result );
56 | }
57 |
58 | - (NSString *) base64EncodedString
59 | {
60 | NSData * charData = b64_encode( self );
61 | return ( [[NSString alloc] initWithData: charData encoding: NSUTF8StringEncoding] );
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 23/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | #import "ViewController.h"
12 |
13 | @implementation AppDelegate
14 |
15 |
16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
17 | {
18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
19 | // Override point for customization after application launch.
20 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
21 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
22 | } else {
23 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
24 | }
25 | self.window.rootViewController = self.viewController;
26 | [self.window makeKeyAndVisible];
27 | return YES;
28 | }
29 |
30 | - (void)applicationWillResignActive:(UIApplication *)application
31 | {
32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
33 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
34 | }
35 |
36 | - (void)applicationDidEnterBackground:(UIApplication *)application
37 | {
38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
40 | }
41 |
42 | - (void)applicationWillEnterForeground:(UIApplication *)application
43 | {
44 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
45 | }
46 |
47 | - (void)applicationDidBecomeActive:(UIApplication *)application
48 | {
49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
50 | }
51 |
52 | - (void)applicationWillTerminate:(UIApplication *)application
53 | {
54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/src/ShakingAlertView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ShakingAlertView.h
3 | //
4 | // Created by Luke on 21/09/2012.
5 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
6 | //
7 | // https://github.com/stringer630/ShakingAlertView
8 | //
9 |
10 | // This code is distributed under the terms and conditions of the MIT license.
11 | //
12 | // Copyright (c) 2012 Luke Stringer
13 | //
14 | // Permission is hereby granted, free of charge, to any person obtaining a copy
15 | // of this software and associated documentation files (the "Software"), to deal
16 | // in the Software without restriction, including without limitation the rights
17 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | // copies of the Software, and to permit persons to whom the Software is
19 | // furnished to do so, subject to the following conditions:
20 | //
21 | // The above copyright notice and this permission notice shall be included in
22 | // all copies or substantial portions of the Software.
23 | //
24 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 | // THE SOFTWARE.
31 |
32 | #import
33 |
34 | typedef enum {
35 | HashTechniqueNone,
36 | HashTechniqueSHA1,
37 | HashTechniqueMD5
38 | } HashTechnique;
39 |
40 |
41 | @interface ShakingAlertView : UIAlertView
42 |
43 | @property (nonatomic, strong) NSString *password;
44 |
45 | @property (nonatomic, copy) void(^onCorrectPassword)();
46 | @property (nonatomic, copy) void(^onDismissalWithoutPassword)();
47 |
48 | @property (assign) HashTechnique hashTechnique;
49 |
50 |
51 | // Constructors for plaintext password
52 | - (id)initWithAlertTitle:(NSString *)title
53 | checkForPassword:(NSString *)password;
54 |
55 | - (id)initWithAlertTitle:(NSString *)title
56 | checkForPassword:(NSString *)password
57 | onCorrectPassword:(void(^)())correctPasswordBlock
58 | onDismissalWithoutPassword:(void(^)())dismissalWithoutPasswordBlock;
59 |
60 |
61 | // Constructors for hashed passwords
62 | - (id)initWithAlertTitle:(NSString *)title
63 | checkForPassword:(NSString *)password
64 | usingHashingTechnique:(HashTechnique)hashingTechnique;
65 |
66 | - (id)initWithAlertTitle:(NSString *)title
67 | checkForPassword:(NSString *)password
68 | usingHashingTechnique:(HashTechnique)hashingTechnique
69 | onCorrectPassword:(void(^)())correctPasswordBlock
70 | onDismissalWithoutPassword:(void(^)())dismissalWithoutPasswordBlock;
71 |
72 | @end
73 |
74 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcodeproj/xcshareddata/xcschemes/ShakingAlertView.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 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // ShakingAlertView
4 | //
5 | // Created by Luke on 21/09/2012.
6 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
7 | //
8 | //
9 | //
10 |
11 | #import "ViewController.h"
12 | #import "ModalViewController.h"
13 |
14 | @implementation ViewController
15 |
16 | #pragma mark - IBActions
17 | - (IBAction)plainTextLoginTapped:(id)sender {
18 |
19 | // Make the alert
20 | // Here was are using a plantext password check
21 | ShakingAlertView *shakingAlert = [[ShakingAlertView alloc] initWithAlertTitle:@"Enter Password"
22 | checkForPassword:@"password"];
23 |
24 | // Block to excute on success
25 | [shakingAlert setOnCorrectPassword:^{
26 | // Show a modal view
27 | [self showModalView];
28 |
29 | }];
30 |
31 | // Block to execute on alert dismissal
32 | [shakingAlert setOnDismissalWithoutPassword:^{
33 | // Show regular UIAlertView to give them another go
34 | [self showFailedPasswordAlert];
35 |
36 | }];
37 |
38 | // Show and release
39 | [shakingAlert show];
40 |
41 | }
42 |
43 | - (IBAction)sha1LoginTapped:(id)sender {
44 | // Make the alert
45 | // Speficify we want to use SHA1 hashing
46 | ShakingAlertView *shakingAlert = [[ShakingAlertView alloc]
47 | initWithAlertTitle:@"Enter Password"
48 | checkForPassword:@"W6ph5Mm5Pz8GgiULbPgzG37mj9g=" //SHA1 hash of 'password'
49 | usingHashingTechnique:HashTechniqueSHA1];
50 |
51 | // Block to excute on success
52 | [shakingAlert setOnCorrectPassword:^{
53 | // Show a modal view
54 | [self showModalView];
55 |
56 | }];
57 |
58 | // Block to execute on alert dismissal
59 | [shakingAlert setOnDismissalWithoutPassword:^{
60 | // Show regular UIAlertView to give them another go
61 | [self showFailedPasswordAlert];
62 |
63 | }];
64 |
65 |
66 | // Show and release
67 | [shakingAlert show];
68 |
69 | }
70 |
71 | - (IBAction)md5LoginTaped:(id)sender {
72 |
73 | // Make the alert
74 | // Speficify we want to use MD5 hashing
75 | // Here we use a constructor that also takes the blocks
76 | ShakingAlertView *shakingAlert = [[ShakingAlertView alloc]
77 | initWithAlertTitle:@"Enter Password"
78 | checkForPassword:@"X03MO1qnZdYdgyfeuILPmQ==" //MD5 hash of 'password'
79 | usingHashingTechnique:HashTechniqueMD5
80 | onCorrectPassword:^{
81 | // Show a modal view
82 | [self showModalView];
83 | }
84 | onDismissalWithoutPassword:^{
85 | // Show regular UIAlertView to give them another go
86 | [self showFailedPasswordAlert];
87 |
88 | }];
89 |
90 |
91 | // Show and release
92 | [shakingAlert show];
93 | }
94 |
95 | #pragma mark - Others
96 | - (void)showModalView {
97 |
98 | ModalViewController *modalVC = nil;
99 |
100 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
101 | modalVC = [[ModalViewController alloc] initWithNibName:@"ModalViewController_iPhone" bundle:nil];
102 | } else {
103 | modalVC = [[ModalViewController alloc] initWithNibName:@"ModalViewController_iPad" bundle:nil];
104 | }
105 |
106 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:modalVC];
107 | navController.modalPresentationStyle = UIModalPresentationFormSheet;
108 |
109 | [self presentModalViewController:navController animated:YES];
110 |
111 | }
112 |
113 | - (void)showFailedPasswordAlert {
114 | UIAlertView *alert = [[UIAlertView alloc]
115 | initWithTitle:@"Failed Password Entry"
116 | message:@"To access the password protected view you must enter a valid password. Try again?"
117 | delegate:self
118 | cancelButtonTitle:@"No"
119 | otherButtonTitles:@"Yes", nil];
120 | [alert show];
121 | }
122 |
123 | #pragma mark - UIAlertViewDelegate
124 |
125 | - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
126 |
127 | // Give them another go at entering correct password
128 | if (buttonIndex != alertView.cancelButtonIndex) {
129 | [self plainTextLoginTapped:nil];
130 | }
131 | }
132 |
133 |
134 | @end
135 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ShakingAlertView
2 | ===================
3 |
4 | [](https://travis-ci.org/lukestringer90/ShakingAlertView)
5 | 
6 |
7 | ShakingAlertView is a UIAlertView subclass with a password entry textfield. Incorrect password entry causes a "shake" animation similar to the OS X account login screen.
8 |
9 | 
10 |
11 | ## Installation
12 | ### Cocoapods
13 | Add to your Podfile:
14 |
15 | ```
16 | pod 'ShakingAlertView'
17 | ```
18 |
19 | ### Adding source code manually
20 | Clone the git repo and drag the **"src"** folder into your project. This contains the UI components and cryptographic helpers necessary for hashing passwords.
21 |
22 | ## Usage
23 | ### Plaintext password
24 |
25 | Use ShakingAlertView just like UIAlertView. For a checking a plain text password:
26 |
27 | ```
28 | ShakingAlertView *shakingAlert = nil;
29 | shakingAlert = [[ShakingAlertView alloc] initWithAlertTitle:@"Enter Password"
30 | checkForPassword:@"pass"];
31 |
32 | [shakingAlert setOnCorrectPassword:^{
33 | // Code to execute on correct password entry
34 | }];
35 |
36 | [shakingAlert setOnDismissalWithoutPassword:^{
37 | // Code to execute on alert dismissal without password entry
38 | }];
39 |
40 | [shakingAlert show];
41 | ```
42 |
43 | Rather than using a delegate, pass the instance a completion block to be executed for correct password entry and alert dismissal. ShakingAlertView uses ARC so no need to release your instances.
44 |
45 | ### Hashed passwords
46 |
47 | ShakingAlertView uses the [Common Crypto](https://developer.apple.com/library/mac/documentation/security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW4) C API to hash the entered text to SHA1 or MD5. Therefore if you only know the hashed counterpart of a password string you can specify this along with the hashing algorithm type in the constructor.
48 |
49 | ```
50 | ShakingAlertView *shakingAlert = nil;
51 | shakingAlert = [[ShakingAlertView alloc] initWithAlertTitle:@"Enter Password"
52 | checkForPassword:@"W6ph5Mm5Pz8GgiULbPgzG37mj9g=" //sha1 hash of 'password'
53 | usingHashingTechnique:HashTechniqueSHA1];
54 |
55 | ```
56 |
57 | The hashing algorithm to use is defined by an enum and passed into the constructor.
58 | ```
59 | typedef enum {
60 | HashTechniqueNone,
61 | HashTechniqueSHA1,
62 | HashTechniqueMD5
63 | } HashTechnique;
64 | ```
65 |
66 | `HashTechniqueNone` is used if no technique is specified, like in the `initWithAlertTitle:checkForPassword` and `initWithAlertTitle:checkForPassword:onCorrectPassword:onDismissalWithoutPassword` constructors. Here the entered string is compared with the specified plaintext password using a simple `isEqualToString:` evaluation.
67 |
68 | ## Running the tests
69 | The ShakingAlertView class is tested using the BDD tool [Kiwi](https://github.com/allending/Kiwi). To run the tests install Kiwi via [Cocoapods](http://cocoapods.org), and the open the workspace:
70 |
71 | ```
72 | cd Example\ Project/
73 | pod install
74 | open ExampleProject.xcworkspace/
75 | ````
76 |
77 | Make sure the **"ShakingAlertView"** scheme is selected then run the tests with **⌘+U**
78 |
79 | ## Acknowledgements
80 | `NSData+Base64.h/m` and `b64.h/m` from [aqtoolkit](https://github.com/AlanQuatermain/aqtoolkit) by [Jim Dovey](https://github.com/AlanQuatermain)
81 |
82 | [Kiwi](https://github.com/allending/Kiwi) testing tool.
83 |
84 | ## Licence
85 | This code is distributed under the terms and conditions of the MIT license.
86 |
87 | Copyright (c) 2012 Luke Stringer
88 |
89 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
90 |
91 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
92 |
93 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
94 |
95 | ---
96 |
97 | ### Author
98 |
99 | Follow me on twitter: [lukestringer90](http://twitter.com/lukestringer90)
100 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ModalViewController_iPhone.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1296
5 | 12B19
6 | 2549
7 | 1187
8 | 624.00
9 |
13 |
14 | IBProxyObject
15 | IBUILabel
16 | IBUIView
17 |
18 |
19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
20 |
21 |
25 |
26 |
30 |
34 |
83 |
84 |
85 |
86 |
87 |
88 | view
89 |
90 |
91 |
92 | 3
93 |
94 |
95 |
96 |
97 |
98 | 0
99 |
100 |
101 |
102 |
103 |
104 | 1
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | -1
113 |
114 |
115 | File's Owner
116 |
117 |
118 | -2
119 |
120 |
121 |
122 |
123 | 4
124 |
125 |
126 |
127 |
128 |
129 |
130 | ModalViewController
131 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
132 | UIResponder
133 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
134 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
135 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
136 |
137 |
138 |
139 |
140 |
141 | 4
142 |
143 |
144 | 0
145 | IBCocoaTouchFramework
146 |
147 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
148 |
149 |
150 | YES
151 | 3
152 | 1498
153 |
154 |
155 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/ModalViewController_iPad.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1296
5 | 12B19
6 | 2549
7 | 1187
8 | 624.00
9 |
10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
11 | 1498
12 |
13 |
14 | IBProxyObject
15 | IBUILabel
16 | IBUIView
17 |
18 |
19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
20 |
21 |
22 | PluginDependencyRecalculationVersion
23 |
24 |
25 |
26 |
27 | IBFilesOwner
28 | IBIPadFramework
29 |
30 |
31 | IBFirstResponder
32 | IBIPadFramework
33 |
34 |
35 |
36 | 274
37 |
38 |
39 |
40 | 292
41 | {{174, 267}, {193, 21}}
42 |
43 | _NS:9
44 | NO
45 | YES
46 | 7
47 | NO
48 | IBIPadFramework
49 | Password protected view
50 |
51 | 1
52 | MCAwIDAAA
53 |
54 |
55 | 0
56 | 10
57 |
58 | 1
59 | 17
60 |
61 |
62 | Helvetica
63 | 17
64 | 16
65 |
66 |
67 |
68 | {{0, 64}, {540, 556}}
69 |
70 |
71 |
72 | 3
73 | MQA
74 |
75 | 2
76 |
77 |
78 |
79 | 2
80 |
81 |
82 | NO
83 |
84 |
85 | IBUIModalFormSheetSimulatedSizeMetrics
86 |
87 | YES
88 |
89 |
90 |
91 |
92 |
93 | {540, 620}
94 | {540, 620}
95 |
96 |
97 | IBIPadFramework
98 | Form Sheet
99 |
100 | IBIPadFramework
101 |
102 |
103 |
104 |
105 |
106 |
107 | view
108 |
109 |
110 |
111 | 3
112 |
113 |
114 |
115 |
116 |
117 | 0
118 |
119 |
120 |
121 |
122 |
123 | -1
124 |
125 |
126 | File's Owner
127 |
128 |
129 | -2
130 |
131 |
132 |
133 |
134 | 2
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | 8
143 |
144 |
145 |
146 |
147 |
148 |
149 | ModalViewController
150 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
151 | UIResponder
152 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
153 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
154 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
155 |
156 |
157 |
158 |
159 |
160 | 8
161 |
162 |
163 | 0
164 | IBIPadFramework
165 |
166 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
167 |
168 |
169 | YES
170 | 3
171 | 1498
172 |
173 |
174 |
--------------------------------------------------------------------------------
/src/b64.m:
--------------------------------------------------------------------------------
1 | /*
2 | * b64.m
3 | * AQToolkit
4 | *
5 | * Created by Jim Dovey on 11-01-11.
6 | * Based on b64.c by Bob Trower
7 | *
8 | *
9 | */
10 | /*********************************************************************\
11 |
12 | MODULE NAME: b64.c
13 |
14 | AUTHOR: Bob Trower 08/04/01
15 |
16 | PROJECT: Crypt Data Packaging
17 |
18 | COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001
19 |
20 | NOTE: This source code may be used as you wish, subject to
21 | the MIT license. See the LICENCE section below.
22 | DESCRIPTION:
23 | This little utility implements the Base64
24 | Content-Transfer-Encoding standard described in
25 | RFC1113 (http://www.faqs.org/rfcs/rfc1113.html).
26 |
27 | This is the coding scheme used by MIME to allow
28 | binary data to be transferred by SMTP mail.
29 |
30 | Groups of 3 bytes from a binary stream are coded as
31 | groups of 4 bytes in a text stream.
32 |
33 | The input stream is 'padded' with zeros to create
34 | an input that is an even multiple of 3.
35 |
36 | A special character ('=') is used to denote padding so
37 | that the stream can be decoded back to its exact size.
38 |
39 | Encoded output is formatted in lines which should
40 | be a maximum of 72 characters to conform to the
41 | specification. This program defaults to 72 characters,
42 | but will allow more or less through the use of a
43 | switch. The program enforces a minimum line size
44 | of 4 characters.
45 |
46 | Example encoding:
47 |
48 | The stream 'ABCD' is 32 bits long. It is mapped as
49 | follows:
50 |
51 | ABCD
52 |
53 | A (65) B (66) C (67) D (68) (None) (None)
54 | 01000001 01000010 01000011 01000100
55 |
56 | 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=)
57 | 010000 010100 001001 000011 010001 000000 000000 000000
58 |
59 |
60 | QUJDRA==
61 |
62 | Decoding is the process in reverse. A 'decode' lookup
63 | table has been created to avoid string scans.
64 |
65 | LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
66 |
67 | Permission is hereby granted, free of charge, to any person
68 | obtaining a copy of this software and associated
69 | documentation files (the "Software"), to deal in the
70 | Software without restriction, including without limitation
71 | the rights to use, copy, modify, merge, publish, distribute,
72 | sublicense, and/or sell copies of the Software, and to
73 | permit persons to whom the Software is furnished to do so,
74 | subject to the following conditions:
75 |
76 | The above copyright notice and this permission notice shall
77 | be included in all copies or substantial portions of the
78 | Software.
79 |
80 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
81 | KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
82 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
83 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
84 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
85 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
86 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
87 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
88 |
89 | VERSION HISTORY:
90 | Bob Trower 08/04/01 -- Create Version 0.00.00B
91 |
92 | \******************************************************************* */
93 |
94 | #import "b64.h"
95 | #import
96 |
97 | /*
98 | ** Translation Table as described in RFC1113
99 | */
100 | static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
101 |
102 | /*
103 | ** Translation Table to decode (created by author)
104 | */
105 | static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
106 |
107 | /*
108 | ** encodeblock
109 | **
110 | ** encode 3 8-bit binary bytes as 4 '6-bit' characters
111 | */
112 | static void encodeblock( unsigned char in[3], unsigned char out[4], int len )
113 | {
114 | out[0] = cb64[ in[0] >> 2 ];
115 | out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
116 | out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
117 | out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
118 | }
119 |
120 | /*
121 | ** encode
122 | **
123 | ** base64 encode a stream adding padding and line breaks as per spec.
124 | */
125 | NSData * b64_encode( NSData * data )
126 | {
127 | uint8_t in[3], out[4];
128 | int i, len;
129 |
130 | const uint8_t *bytes = (const uint8_t *)[data bytes];
131 | NSUInteger bytesLen = [data length];
132 | NSUInteger offset = 0;
133 |
134 | NSMutableData * outputData = [[NSMutableData alloc] initWithCapacity: bytesLen + (bytesLen/4) + 1];
135 |
136 | while( offset < bytesLen )
137 | {
138 | len = 0;
139 | for( i = 0; i < 3; i++ )
140 | {
141 | if ( offset < bytesLen )
142 | {
143 | in[i] = bytes[offset++];
144 | len++;
145 | }
146 | else
147 | {
148 | in[i] = 0;
149 | }
150 | }
151 |
152 | if ( len != 0 )
153 | {
154 | encodeblock( in, out, len );
155 | [outputData appendBytes: out length: 4];
156 | }
157 | }
158 |
159 | NSData * result = [outputData copy];
160 | return ( result );
161 | }
162 |
163 | /*
164 | ** decodeblock
165 | **
166 | ** decode 4 '6-bit' characters into 3 8-bit binary bytes
167 | */
168 | void decodeblock( unsigned char in[4], unsigned char out[3] )
169 | {
170 | out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
171 | out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
172 | out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
173 | }
174 |
175 | /*
176 | ** decode
177 | **
178 | ** decode a base64 encoded stream discarding padding, line breaks and noise
179 | */
180 | NSData * b64_decode( NSData * data )
181 | {
182 | uint8_t in[4], out[3], v;
183 | int i, len;
184 |
185 | const uint8_t *bytes = (const uint8_t *)[data bytes];
186 | NSUInteger bytesLen = [data length];
187 | NSUInteger offset = 0;
188 |
189 | NSMutableData * outputData = [[NSMutableData alloc] initWithCapacity: bytesLen];
190 |
191 | while ( offset < bytesLen )
192 | {
193 | for ( len = 0, i = 0; i < 4 && offset < bytesLen; i++ )
194 | {
195 | v = 0;
196 | while ( offset < bytesLen && v == 0 )
197 | {
198 | v = bytes[offset++];
199 | v = ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);
200 |
201 | if ( v != 0 )
202 | {
203 | v = ((v == '$') ? 0 : v - 61);
204 | }
205 | }
206 |
207 | if ( (offset < (bytesLen+1)) && (v != 0) )
208 | {
209 | len++;
210 | if ( v != 0 )
211 | {
212 | in[ i ] = (v - 1);
213 | }
214 | }
215 | else
216 | {
217 | in[i] = 0;
218 | }
219 | }
220 |
221 | if ( len )
222 | {
223 | decodeblock( in, out );
224 | [outputData appendBytes: out length: len-1];
225 | }
226 | }
227 |
228 | NSData * result = [outputData copy];
229 | return ( result );
230 | }
231 |
--------------------------------------------------------------------------------
/src/ShakingAlertView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ShakingAlertView.m
3 | //
4 | // Created by Luke on 21/09/2012.
5 | // Copyright (c) 2012 Luke Stringer. All rights reserved.
6 | //
7 | // https://github.com/stringer630/ShakingAlertView
8 | //
9 |
10 | // This code is distributed under the terms and conditions of the MIT license.
11 | //
12 | // Copyright (c) 2012 Luke Stringer
13 | //
14 | // Permission is hereby granted, free of charge, to any person obtaining a copy
15 | // of this software and associated documentation files (the "Software"), to deal
16 | // in the Software without restriction, including without limitation the rights
17 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 | // copies of the Software, and to permit persons to whom the Software is
19 | // furnished to do so, subject to the following conditions:
20 | //
21 | // The above copyright notice and this permission notice shall be included in
22 | // all copies or substantial portions of the Software.
23 | //
24 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 | // THE SOFTWARE.
31 |
32 | #import "ShakingAlertView.h"
33 | #include
34 | #import "NSData+Base64.h"
35 |
36 |
37 | @interface ShakingAlertView ()
38 | // Private property as other instances shouldn't interact with this directly
39 | @property (nonatomic, strong) UITextField *passwordField;
40 | @end
41 |
42 | // Enum for alert view button index
43 | typedef enum {
44 | ShakingAlertViewButtonIndexDismiss = 0,
45 | ShakingAlertViewButtonIndexSuccess = 10
46 | } ShakingAlertViewButtonIndex;
47 |
48 | @implementation ShakingAlertView
49 |
50 | #pragma mark - Constructors
51 |
52 | - (id)initWithAlertTitle:(NSString *)title
53 | checkForPassword:(NSString *)password{
54 |
55 | self = [super initWithTitle:title
56 | message:@"---blank---" // password field will go here
57 | delegate:self
58 | cancelButtonTitle:@"Cancel"
59 | otherButtonTitles:@"Enter", nil];
60 | if (self) {
61 | self.password = password;
62 | self.hashTechnique = HashTechniqueNone; // use no hashing by default
63 | }
64 |
65 | return self;
66 | }
67 |
68 | - (id)initWithAlertTitle:(NSString *)title
69 | checkForPassword:(NSString *)password
70 | onCorrectPassword:(void(^)())correctPasswordBlock
71 | onDismissalWithoutPassword:(void(^)())dismissalWithoutPasswordBlock {
72 |
73 | self = [self initWithAlertTitle:title checkForPassword:password];
74 | if (self) {
75 | self.onCorrectPassword = correctPasswordBlock;
76 | self.onDismissalWithoutPassword = dismissalWithoutPasswordBlock;
77 | }
78 |
79 |
80 | return self;
81 |
82 | }
83 |
84 | - (id)initWithAlertTitle:(NSString *)title
85 | checkForPassword:(NSString *)password
86 | usingHashingTechnique:(HashTechnique)hashingTechnique {
87 |
88 | self = [self initWithAlertTitle:title checkForPassword:password];
89 | if (self) {
90 | self.hashTechnique = hashingTechnique;
91 | }
92 | return self;
93 |
94 | }
95 |
96 | - (id)initWithAlertTitle:(NSString *)title
97 | checkForPassword:(NSString *)password
98 | usingHashingTechnique:(HashTechnique)hashingTechnique
99 | onCorrectPassword:(void(^)())correctPasswordBlock
100 | onDismissalWithoutPassword:(void(^)())dismissalWithoutPasswordBlock {
101 |
102 |
103 | self = [self initWithAlertTitle:title checkForPassword:password usingHashingTechnique:hashingTechnique];
104 | if (self) {
105 | self.onCorrectPassword = correctPasswordBlock;
106 | self.onDismissalWithoutPassword = dismissalWithoutPasswordBlock;
107 | }
108 |
109 |
110 | return self;
111 |
112 | }
113 |
114 | // Override show method to add the password field
115 | - (void)show {
116 |
117 | // Textfield for the password
118 | // Position it over the message section of the alert
119 | UITextField *passwordField = [[UITextField alloc] initWithFrame:CGRectMake(14, 45, 256, 25)];
120 | passwordField.secureTextEntry = YES;
121 | passwordField.placeholder = @"password";
122 | passwordField.backgroundColor = [UIColor whiteColor];
123 |
124 | // Pad out the left side of the view to properly inset the text
125 | UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 6, 19)];
126 | passwordField.leftView = paddingView;
127 | passwordField.leftViewMode = UITextFieldViewModeAlways;
128 |
129 | // Set delegate
130 | passwordField.delegate = self;
131 |
132 | // Set as property
133 | self.passwordField = passwordField;
134 |
135 | // Add to subview
136 | [self addSubview:_passwordField];
137 |
138 | // Show alert
139 | [super show];
140 |
141 | // present keyboard for text entry
142 | [_passwordField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
143 |
144 | }
145 |
146 | - (void)animateIncorrectPassword {
147 | // Clear the password field
148 | _passwordField.text = nil;
149 |
150 | // Animate the alert to show that the entered string was wrong
151 | // "Shakes" similar to OS X login screen
152 | CGAffineTransform moveRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0);
153 | CGAffineTransform moveLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -20, 0);
154 | CGAffineTransform resetTransform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0);
155 |
156 | [UIView animateWithDuration:0.1 animations:^{
157 | // Translate left
158 | self.transform = moveLeft;
159 |
160 | } completion:^(BOOL finished) {
161 |
162 | [UIView animateWithDuration:0.1 animations:^{
163 |
164 | // Translate right
165 | self.transform = moveRight;
166 |
167 | } completion:^(BOOL finished) {
168 |
169 | [UIView animateWithDuration:0.1 animations:^{
170 |
171 | // Translate left
172 | self.transform = moveLeft;
173 |
174 | } completion:^(BOOL finished) {
175 |
176 | [UIView animateWithDuration:0.1 animations:^{
177 |
178 | // Translate to origin
179 | self.transform = resetTransform;
180 | }];
181 | }];
182 |
183 | }];
184 | }];
185 |
186 | }
187 |
188 | #pragma mark - UIAlertViewDelegate
189 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
190 |
191 | // If "Enter" button pressed on alert view then check password
192 | if (buttonIndex == alertView.firstOtherButtonIndex) {
193 |
194 | if ([self enteredTextIsCorrect]) {
195 |
196 | // Hide keyboard
197 | [self.passwordField resignFirstResponder];
198 |
199 | // Dismiss with success
200 | [alertView dismissWithClickedButtonIndex:ShakingAlertViewButtonIndexSuccess animated:YES];
201 |
202 | }
203 |
204 | // If incorrect then animate
205 | else {
206 | [self animateIncorrectPassword];
207 | }
208 | }
209 | }
210 |
211 |
212 | // Overide to customise when alert is dimsissed
213 | - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated {
214 |
215 | // Only dismiss for ShakingAlertViewButtonIndexDismiss or ShakingAlertViewButtonIndexSuccess
216 | // This means we don't dissmis for the case where "Enter" button is pressed and password is incorrect
217 | switch (buttonIndex) {
218 | case ShakingAlertViewButtonIndexSuccess:
219 | [super dismissWithClickedButtonIndex:ShakingAlertViewButtonIndexDismiss animated:animated];
220 | [self safeCallBlock:self.onCorrectPassword];
221 | break;
222 | case ShakingAlertViewButtonIndexDismiss:
223 | [super dismissWithClickedButtonIndex:ShakingAlertViewButtonIndexDismiss animated:animated];
224 | [self safeCallBlock:self.onDismissalWithoutPassword];
225 | break;
226 | default:
227 | break;
228 | }
229 |
230 | }
231 |
232 | #pragma mark - UITextFieldDelegate
233 | - (BOOL)textFieldShouldReturn:(UITextField *)textField {
234 | // Check password
235 | if ([self enteredTextIsCorrect]) {
236 |
237 | // Hide keyboard
238 | [self.passwordField resignFirstResponder];
239 |
240 | // Dismiss with success
241 | [self dismissWithClickedButtonIndex:ShakingAlertViewButtonIndexSuccess animated:YES];
242 |
243 | return YES;
244 | }
245 |
246 | // Password is incorrect to so animate
247 | [self animateIncorrectPassword];
248 | return NO;
249 | }
250 |
251 | #pragma mark - Private helpers
252 | - (void)safeCallBlock:(void (^)(void))block {
253 | // Only call the block is not nil
254 | if (block) {
255 | block();
256 | }
257 | }
258 |
259 | - (BOOL)enteredTextIsCorrect {
260 | switch (_hashTechnique) {
261 |
262 | // No hashing algorithm used
263 | case HashTechniqueNone:
264 | return [_passwordField.text isEqualToString:_password];
265 | break;
266 |
267 |
268 | // SHA1 used
269 | case HashTechniqueSHA1: {
270 |
271 | unsigned char digest[CC_SHA1_DIGEST_LENGTH];
272 | NSData *stringBytes = [_passwordField.text dataUsingEncoding: NSUTF8StringEncoding];
273 | CC_SHA1([stringBytes bytes], [stringBytes length], digest);
274 |
275 | NSData *pwHashData = [[NSData alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
276 | NSString *hashedEnteredPassword = [pwHashData base64EncodedString];
277 |
278 | return [hashedEnteredPassword isEqualToString:_password];
279 |
280 | }
281 | break;
282 |
283 |
284 | // MD5 used
285 | case HashTechniqueMD5: {
286 |
287 | unsigned char digest[CC_MD5_DIGEST_LENGTH];
288 | NSData *stringBytes = [_passwordField.text dataUsingEncoding: NSUTF8StringEncoding];
289 | CC_MD5([stringBytes bytes], [stringBytes length], digest);
290 |
291 | NSData *pwHashData = [[NSData alloc] initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
292 | NSString *hashedEnteredPassword = [pwHashData base64EncodedString];
293 |
294 | return [hashedEnteredPassword isEqualToString:_password];
295 |
296 | }
297 | break;
298 |
299 | default:
300 | break;
301 | }
302 |
303 |
304 | // To stop Xcode complaining return NO by default
305 | return NO;
306 |
307 | }
308 |
309 | #pragma mark - Memory Managment
310 |
311 |
312 | @end
313 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/en.lproj/ViewController_iPad.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1296
5 | 12C54
6 | 2549
7 | 1187.34
8 | 625.00
9 |
10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
11 | 1498
12 |
13 |
14 | IBProxyObject
15 | IBUIButton
16 | IBUIView
17 |
18 |
19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
20 |
21 |
22 | PluginDependencyRecalculationVersion
23 |
24 |
25 |
26 |
27 | IBFilesOwner
28 | IBIPadFramework
29 |
30 |
31 | IBFirstResponder
32 | IBIPadFramework
33 |
34 |
35 |
36 | 274
37 |
38 |
39 |
40 | 292
41 | {{252, 366}, {265, 37}}
42 |
43 |
44 |
45 | _NS:9
46 | NO
47 | IBIPadFramework
48 | 0
49 | 0
50 | 1
51 | Access Password Protected View
52 |
53 | 3
54 | MQA
55 |
56 |
57 | 1
58 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
59 |
60 |
61 | 3
62 | MC41AA
63 |
64 |
65 | 2
66 | 15
67 |
68 |
69 | Helvetica-Bold
70 | 15
71 | 16
72 |
73 |
74 |
75 |
76 | 292
77 | {{252, 482}, {265, 37}}
78 |
79 |
80 |
81 | _NS:9
82 | NO
83 | IBIPadFramework
84 | 0
85 | 0
86 | 1
87 | Login With Plain SHA1 Password
88 |
89 |
90 | 1
91 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | 292
100 | {{252, 590}, {265, 37}}
101 |
102 |
103 |
104 | _NS:9
105 | NO
106 | IBIPadFramework
107 | 0
108 | 0
109 | 1
110 | Login With Plain MD5 Password
111 |
112 |
113 | 1
114 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
115 |
116 |
117 |
118 |
119 |
120 |
121 | {{0, 20}, {768, 1004}}
122 |
123 |
124 |
125 |
126 | 3
127 | MQA
128 |
129 | 2
130 |
131 |
132 |
133 | 2
134 |
135 | IBIPadFramework
136 |
137 |
138 |
139 |
140 |
141 |
142 | view
143 |
144 |
145 |
146 | 3
147 |
148 |
149 |
150 | plainTextLoginTapped:
151 |
152 |
153 | 7
154 |
155 | 8
156 |
157 |
158 |
159 | sha1LoginTapped:
160 |
161 |
162 | 7
163 |
164 | 12
165 |
166 |
167 |
168 | md5LoginTaped:
169 |
170 |
171 | 7
172 |
173 | 11
174 |
175 |
176 |
177 |
178 |
179 | 0
180 |
181 |
182 |
183 |
184 |
185 | -1
186 |
187 |
188 | File's Owner
189 |
190 |
191 | -2
192 |
193 |
194 |
195 |
196 | 2
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 | 4
207 |
208 |
209 |
210 |
211 | 9
212 |
213 |
214 |
215 |
216 | 10
217 |
218 |
219 |
220 |
221 |
222 |
223 | ViewController
224 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
225 | UIResponder
226 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
227 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
228 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
229 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
230 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
231 |
232 |
233 |
234 |
235 |
236 | 12
237 |
238 |
239 |
240 |
241 | ViewController
242 | UIViewController
243 |
244 | id
245 | id
246 | id
247 |
248 |
249 |
250 | md5LoginTaped:
251 | id
252 |
253 |
254 | plainTextLoginTapped:
255 | id
256 |
257 |
258 | sha1LoginTapped:
259 | id
260 |
261 |
262 |
263 | IBProjectSource
264 | ./Classes/ViewController.h
265 |
266 |
267 |
268 |
269 | 0
270 | IBIPadFramework
271 |
272 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
273 |
274 |
275 | YES
276 | 3
277 | 1498
278 |
279 |
280 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject/en.lproj/ViewController_iPhone.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 1296
5 | 12C54
6 | 2549
7 | 1187.34
8 | 625.00
9 |
10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
11 | 1498
12 |
13 |
14 | IBProxyObject
15 | IBUIButton
16 | IBUIView
17 |
18 |
19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
20 |
21 |
22 | PluginDependencyRecalculationVersion
23 |
24 |
25 |
26 |
27 | IBFilesOwner
28 | IBCocoaTouchFramework
29 |
30 |
31 | IBFirstResponder
32 | IBCocoaTouchFramework
33 |
34 |
35 |
36 | 274
37 |
38 |
39 |
40 | 292
41 | {{28, 89}, {265, 37}}
42 |
43 |
44 | _NS:9
45 | NO
46 | IBCocoaTouchFramework
47 | 0
48 | 0
49 | 1
50 | Login With Plain Text Password
51 |
52 | 3
53 | MQA
54 |
55 |
56 | 1
57 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
58 |
59 |
60 | 3
61 | MC41AA
62 |
63 |
64 | 2
65 | 15
66 |
67 |
68 | Helvetica-Bold
69 | 15
70 | 16
71 |
72 |
73 |
74 |
75 | 292
76 | {{28, 211}, {265, 37}}
77 |
78 |
79 | _NS:9
80 | NO
81 | IBCocoaTouchFramework
82 | 0
83 | 0
84 | 1
85 | Login With Plain SHA1 Password
86 |
87 |
88 | 1
89 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | 292
98 | {{28, 329}, {265, 37}}
99 |
100 |
101 | _NS:9
102 | NO
103 | IBCocoaTouchFramework
104 | 0
105 | 0
106 | 1
107 | Login With Plain MD5 Password
108 |
109 |
110 | 1
111 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
112 |
113 |
114 |
115 |
116 |
117 |
118 | {{0, 20}, {320, 460}}
119 |
120 |
121 |
122 |
123 | NO
124 |
125 | IBCocoaTouchFramework
126 |
127 |
128 |
129 | 292
130 | {72, 37}
131 | _NS:9
132 | NO
133 | IBCocoaTouchFramework
134 | 0
135 | 0
136 | 1
137 |
138 |
139 | 1
140 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | view
152 |
153 |
154 |
155 | 7
156 |
157 |
158 |
159 | plainTextLoginTapped:
160 |
161 |
162 | 7
163 |
164 | 18
165 |
166 |
167 |
168 | plainTextLoginTapped:
169 |
170 |
171 | 7
172 |
173 | 17
174 |
175 |
176 |
177 | md5LoginTaped:
178 |
179 |
180 | 7
181 |
182 | 21
183 |
184 |
185 |
186 |
187 |
188 | 0
189 |
190 |
191 |
192 |
193 |
194 | -1
195 |
196 |
197 | File's Owner
198 |
199 |
200 | -2
201 |
202 |
203 |
204 |
205 | 6
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 | 8
216 |
217 |
218 |
219 |
220 | 9
221 |
222 |
223 |
224 |
225 | 13
226 |
227 |
228 |
229 |
230 | 15
231 |
232 |
233 |
234 |
235 |
236 |
237 | ViewController
238 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
239 | UIResponder
240 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
241 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
242 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
243 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
244 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
245 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin
246 |
247 |
248 |
249 |
250 |
251 | 21
252 |
253 |
254 |
255 |
256 | ViewController
257 | UIViewController
258 |
259 | id
260 | id
261 | id
262 |
263 |
264 |
265 | md5LoginTaped:
266 | id
267 |
268 |
269 | plainTextLoginTapped:
270 | id
271 |
272 |
273 | sha1LoginTapped:
274 | id
275 |
276 |
277 |
278 | IBProjectSource
279 | ./Classes/ViewController.h
280 |
281 |
282 |
283 |
284 | 0
285 | IBCocoaTouchFramework
286 |
287 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
288 |
289 |
290 | YES
291 | 3
292 | 1498
293 |
294 |
295 |
--------------------------------------------------------------------------------
/Example Project/ShakingAlertViewKiwiTest/ShakingAlertViewTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ShakingAlertViewTests.m
3 | // ExampleProject
4 | //
5 | // Created by Luke on 17/02/2013.
6 | // Copyright 2013 Luke Stringer. All rights reserved.
7 | //
8 |
9 | #import "Kiwi.h"
10 | #import "ShakingAlertView.h"
11 |
12 | // Mirror the class extension in ShakingAlertView.m so we can get to the private parts of the class
13 | @interface ShakingAlertView ()
14 | @property (nonatomic, strong) UITextField *passwordField;
15 | - (void)animateIncorrectPassword;
16 | @end
17 |
18 |
19 | SPEC_BEGIN(ShakingAlertViewTests)
20 |
21 | describe(@"ShakingAlertView", ^{
22 |
23 | context(@"construction", ^{
24 | __block ShakingAlertView *shakingAlertView ;
25 | __block NSString *title;
26 | __block NSString *password;
27 | __block void (^correctPassword)(void);
28 | __block void (^dismissed)(void);
29 |
30 | beforeAll(^{
31 | shakingAlertView = nil;
32 | title = @"Test Title";
33 | password = @"password";
34 | correctPassword = ^(void) { NSLog(@"Correct Password"); };
35 | dismissed = ^(void) { NSLog(@"Dimssed"); };
36 | });
37 |
38 | afterEach(^{
39 | shakingAlertView = nil;
40 | });
41 |
42 | it(@"should not be nil for plaitext password", ^{
43 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
44 | checkForPassword:password];
45 | [shakingAlertView shouldNotBeNil];
46 | });
47 |
48 | it(@"should not be nil for plaintext password and completion blocks", ^{
49 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
50 | checkForPassword:password
51 | onCorrectPassword:correctPassword
52 | onDismissalWithoutPassword:dismissed];
53 | [shakingAlertView shouldNotBeNil];
54 | });
55 |
56 | it(@"should not be nil when using HashTechniqueNone ", ^{
57 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
58 | checkForPassword:password
59 | usingHashingTechnique:HashTechniqueNone];
60 |
61 | [shakingAlertView shouldNotBeNil];
62 |
63 | });
64 |
65 | it(@"should not be nil when using HashTechniqueSHA1 ", ^{
66 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
67 | checkForPassword:password
68 | usingHashingTechnique:HashTechniqueSHA1];
69 |
70 | [shakingAlertView shouldNotBeNil];
71 |
72 | });
73 |
74 | it(@"should not be nil when using HashTechniqueMD5 ", ^{
75 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
76 | checkForPassword:password
77 | usingHashingTechnique:HashTechniqueMD5];
78 |
79 | [shakingAlertView shouldNotBeNil];
80 |
81 | });
82 |
83 | it(@"should not be nil when using a HashTechnique and completion blocks", ^{
84 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
85 | checkForPassword:password
86 | usingHashingTechnique:HashTechniqueMD5
87 | onCorrectPassword:correctPassword
88 | onDismissalWithoutPassword:dismissed];
89 |
90 | [shakingAlertView shouldNotBeNil];
91 |
92 | });
93 |
94 | it(@"should use HashTechniqueNone by default", ^{
95 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
96 | checkForPassword:password];
97 | [[theValue(shakingAlertView.hashTechnique) should] equal:theValue(HashTechniqueNone)];
98 | });
99 |
100 | it(@"should return specified password property after construction", ^{
101 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
102 | checkForPassword:password];
103 | [[shakingAlertView.password should] equal:password];
104 | });
105 |
106 | it(@"should return specified title property after construction", ^{
107 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
108 | checkForPassword:password];
109 | [[shakingAlertView.title should] equal:title];
110 | });
111 |
112 | it(@"should return specified HashTechnique property after construction", ^{
113 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
114 | checkForPassword:password usingHashingTechnique:HashTechniqueSHA1];
115 | [[theValue(shakingAlertView.hashTechnique) should] equal:theValue(HashTechniqueSHA1)];
116 | });
117 |
118 | it(@"should have valid public properties after construction", ^{
119 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
120 | checkForPassword:password
121 | usingHashingTechnique:HashTechniqueMD5
122 | onCorrectPassword:correctPassword
123 | onDismissalWithoutPassword:dismissed];
124 |
125 | [shakingAlertView.title shouldNotBeNil];
126 | [shakingAlertView.password shouldNotBeNil];
127 | [shakingAlertView.onCorrectPassword shouldNotBeNil];
128 | [shakingAlertView.onDismissalWithoutPassword shouldNotBeNil];
129 | [theValue(shakingAlertView.hashTechnique) shouldNotBeNil];
130 |
131 | });
132 |
133 | });
134 | // context end
135 | // ----------------------------------------------
136 |
137 | context(@"alert view buttons tapped", ^{
138 | __block ShakingAlertView *shakingAlertView;
139 | __block NSString *title;
140 | __block NSString *password;
141 |
142 | beforeAll(^{
143 | shakingAlertView = nil;
144 | title = @"Test Title";
145 | password = @"password";
146 | });
147 |
148 | afterEach(^{
149 | shakingAlertView = nil;
150 | });
151 |
152 | it(@"should succeed with button tap and call block for correct password entry", ^{
153 | __block BOOL successReached = NO;
154 | __block BOOL failureReached = NO;
155 | __block int successReachedCount = 0;
156 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
157 | checkForPassword:password
158 | onCorrectPassword:^{
159 | successReached = YES;
160 | successReachedCount++;
161 | }
162 | onDismissalWithoutPassword:^{
163 | failureReached = YES;
164 | }];
165 | [shakingAlertView show];
166 |
167 | // Type and tap OK button
168 | shakingAlertView.passwordField.text = @"password";
169 | [shakingAlertView.delegate alertView:shakingAlertView clickedButtonAtIndex:shakingAlertView.firstOtherButtonIndex];
170 |
171 | // Success block should be called once, and failure should not be called at all
172 | [[theValue(successReached) should] beTrue];
173 | [[theValue(failureReached) shouldNot] beTrue];
174 | [[theValue(successReachedCount) should] equal:theValue(1)];
175 | });
176 |
177 | it(@"should fail with button tap and call block for incorrect password entry", ^{
178 | __block BOOL successReached = NO;
179 | __block BOOL failureReached = NO;
180 | __block int failureReachedCount = 0;
181 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
182 | checkForPassword:password
183 | onCorrectPassword:^{
184 | successReached = YES;
185 | }
186 | onDismissalWithoutPassword:^{
187 | failureReached = YES;
188 | failureReachedCount++;
189 | }];
190 |
191 | [shakingAlertView show];
192 |
193 | // Dismiss it with cancel button
194 | [shakingAlertView dismissWithClickedButtonIndex:shakingAlertView.cancelButtonIndex animated:YES];
195 |
196 | // Failure block should be called once, and sucess should not be called at all
197 | [[theValue(failureReached) should] beTrue];
198 | [[theValue(successReached) shouldNot] beTrue];
199 | [[theValue(failureReachedCount) should] equal:theValue(1)];
200 | });
201 |
202 | it(@"should shake with button for incorrect password entry", ^{
203 | __block BOOL successReached = NO;
204 | __block BOOL failureReached = NO;
205 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
206 | checkForPassword:password onCorrectPassword:^{
207 | successReached = YES;
208 | } onDismissalWithoutPassword:^{
209 | failureReached = YES;
210 | }];
211 | [shakingAlertView show];
212 |
213 | // Type and tap return
214 | // Test the view shakes for the incorrect password
215 | shakingAlertView.passwordField.text = @"incorrect_password";
216 | [[shakingAlertView should] receive:@selector(animateIncorrectPassword)];
217 | [shakingAlertView.delegate alertView:shakingAlertView clickedButtonAtIndex:shakingAlertView.firstOtherButtonIndex];
218 |
219 | // Neither of the completion blocks should have been called
220 | [[theValue(successReached) should] beFalse];
221 | [[theValue(failureReached) should] beFalse];
222 | });
223 | });
224 | // context end
225 | // ----------------------------------------------
226 |
227 | context(@"return key tapped", ^{
228 | __block ShakingAlertView *shakingAlertView;
229 | __block NSString *title;
230 | __block NSString *password;
231 |
232 | beforeAll(^{
233 | shakingAlertView = nil;
234 | title = @"Test Title";
235 | password = @"password";
236 | });
237 |
238 | afterEach(^{
239 | shakingAlertView = nil;
240 | });
241 |
242 | it(@"should succeed with return key and call block for correct password entry", ^{
243 | __block BOOL successReached = NO;
244 | __block BOOL failureReached = NO;
245 | __block int successReachedCount = 0;
246 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
247 | checkForPassword:password
248 | onCorrectPassword:^{
249 | successReached = YES;
250 | successReachedCount++;
251 | }
252 | onDismissalWithoutPassword:^{
253 | failureReached = YES;
254 | }];
255 | [shakingAlertView show];
256 |
257 | // Type and tap return key
258 | shakingAlertView.passwordField.text = @"password";
259 | [shakingAlertView textFieldShouldReturn:shakingAlertView.passwordField];
260 |
261 | // Success block should be called once, and failure should not be called at all
262 | [[theValue(successReached) should] beTrue];
263 | [[theValue(failureReached) shouldNot] beTrue];
264 | [[theValue(successReachedCount) should] equal:theValue(1)];
265 | });
266 |
267 |
268 | it(@"should shake with return key for incorrect password entry", ^{
269 | __block BOOL successReached = NO;
270 | __block BOOL failureReached = NO;
271 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
272 | checkForPassword:password onCorrectPassword:^{
273 | successReached = YES;
274 | } onDismissalWithoutPassword:^{
275 | failureReached = YES;
276 | }];
277 | [shakingAlertView show];
278 |
279 | // Type and tap return key
280 | // Test the view shakes for the incorrect password
281 | shakingAlertView.passwordField.text = @"incorrect_password";
282 | [[shakingAlertView should] receive:@selector(animateIncorrectPassword)];
283 | [shakingAlertView textFieldShouldReturn:shakingAlertView.passwordField];
284 |
285 | // Neither of the completion blocks should have been called
286 | [[theValue(successReached) should] beFalse];
287 | [[theValue(failureReached) should] beFalse];
288 | });
289 | });
290 |
291 | // context end
292 | // ----------------------------------------------
293 |
294 | context(@"SHA1 password checking", ^{
295 | __block ShakingAlertView *shakingAlertView;
296 | __block NSString *title;
297 | __block NSString *SHA1Password;
298 |
299 | beforeAll(^{
300 | shakingAlertView = nil;
301 | title = @"Test Title";
302 | SHA1Password = @"W6ph5Mm5Pz8GgiULbPgzG37mj9g=";
303 | });
304 |
305 | afterEach(^{
306 | shakingAlertView = nil;
307 | });
308 |
309 | it(@"should succeed and call block for correct password entry using SHA1", ^{
310 | __block BOOL successReached = NO;
311 | __block BOOL failureReached = NO;
312 | __block int successReachedCount = 0;
313 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
314 | checkForPassword:SHA1Password
315 | usingHashingTechnique:HashTechniqueSHA1
316 | onCorrectPassword:^{
317 | successReached = YES;
318 | successReachedCount++;
319 | }
320 | onDismissalWithoutPassword:^{
321 | failureReached = YES;
322 | }];
323 |
324 | [shakingAlertView show];
325 |
326 | // Type and tap return key
327 | shakingAlertView.passwordField.text = @"password";
328 | [shakingAlertView textFieldShouldReturn:shakingAlertView.passwordField];
329 |
330 | // Success block should be called once, and failure should not be called at all
331 | [[theValue(successReached) should] beTrue];
332 | [[theValue(failureReached) shouldNot] beTrue];
333 | [[theValue(successReachedCount) should] equal:theValue(1)];
334 | });
335 |
336 | it(@"should fail and call block for incorrect password entry using SHA1", ^{
337 | __block BOOL successReached = NO;
338 | __block BOOL failureReached = NO;
339 | __block int failureReachedCount = 0;
340 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
341 | checkForPassword:SHA1Password
342 | usingHashingTechnique:HashTechniqueSHA1
343 | onCorrectPassword:^{
344 | successReached = YES;
345 | }
346 | onDismissalWithoutPassword:^{
347 | failureReached = YES;
348 | failureReachedCount++;
349 | }];
350 |
351 | [shakingAlertView show];
352 |
353 | // Dismiss it with cancel button
354 | [shakingAlertView dismissWithClickedButtonIndex:shakingAlertView.cancelButtonIndex animated:YES];
355 |
356 | // Failure block should be called once, and sucess should not be called at all
357 | [[theValue(failureReached) should] beTrue];
358 | [[theValue(successReached) shouldNot] beTrue];
359 | [[theValue(failureReachedCount) should] equal:theValue(1)];
360 | });
361 |
362 | it(@"should shake for incorrect password entry using SHA1", ^{
363 | __block BOOL successReached = NO;
364 | __block BOOL failureReached = NO;
365 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
366 | checkForPassword:SHA1Password
367 | usingHashingTechnique:HashTechniqueSHA1
368 | onCorrectPassword:^{
369 | successReached = YES;
370 | } onDismissalWithoutPassword:^{
371 | failureReached = YES;
372 | }];
373 | [shakingAlertView show];
374 |
375 | // Type and tap return
376 | // Test the view shakes for the incorrect password
377 | shakingAlertView.passwordField.text = @"incorrect_password";
378 | [[shakingAlertView should] receive:@selector(animateIncorrectPassword)];
379 | [shakingAlertView.delegate alertView:shakingAlertView clickedButtonAtIndex:shakingAlertView.firstOtherButtonIndex];
380 |
381 | // Neither of the completion blocks should have been called
382 | [[theValue(successReached) should] beFalse];
383 | [[theValue(failureReached) should] beFalse];
384 | });
385 |
386 |
387 | });
388 | // context end
389 | // ----------------------------------------------
390 |
391 | context(@"MD5 password checking", ^{
392 | __block ShakingAlertView *shakingAlertView;
393 | __block NSString *title;
394 | __block NSString *MD5Password;
395 |
396 | beforeAll(^{
397 | shakingAlertView = nil;
398 | title = @"Test Title";
399 | MD5Password = @"X03MO1qnZdYdgyfeuILPmQ==";
400 | });
401 |
402 | afterEach(^{
403 | shakingAlertView = nil;
404 | });
405 |
406 | it(@"should succeed and call block for correct password entry using MD5", ^{
407 | __block BOOL successReached = NO;
408 | __block BOOL failureReached = NO;
409 | __block int successReachedCount = 0;
410 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
411 | checkForPassword:MD5Password
412 | usingHashingTechnique:HashTechniqueMD5
413 | onCorrectPassword:^{
414 | successReached = YES;
415 | successReachedCount++;
416 | }
417 | onDismissalWithoutPassword:^{
418 | failureReached = YES;
419 | }];
420 |
421 | [shakingAlertView show];
422 |
423 | // Type and tap return key
424 | shakingAlertView.passwordField.text = @"password";
425 | [shakingAlertView textFieldShouldReturn:shakingAlertView.passwordField];
426 |
427 | // Success block should be called once, and failure should not be called at all
428 | [[theValue(successReached) should] beTrue];
429 | [[theValue(failureReached) shouldNot] beTrue];
430 | [[theValue(successReachedCount) should] equal:theValue(1)];
431 | });
432 |
433 | it(@"should fail and call block for incorrect password entry using MD5", ^{
434 | __block BOOL successReached = NO;
435 | __block BOOL failureReached = NO;
436 | __block int failureReachedCount = 0;
437 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
438 | checkForPassword:MD5Password
439 | usingHashingTechnique:HashTechniqueMD5
440 | onCorrectPassword:^{
441 | successReached = YES;
442 | }
443 | onDismissalWithoutPassword:^{
444 | failureReached = YES;
445 | failureReachedCount++;
446 | }];
447 |
448 | [shakingAlertView show];
449 |
450 | // Dismiss it with cancel button
451 | [shakingAlertView dismissWithClickedButtonIndex:shakingAlertView.cancelButtonIndex animated:YES];
452 |
453 | // Failure block should be called once, and sucess should not be called at all
454 | [[theValue(failureReached) should] beTrue];
455 | [[theValue(successReached) shouldNot] beTrue];
456 | [[theValue(failureReachedCount) should] equal:theValue(1)];
457 | });
458 |
459 | it(@"should shake for incorrect password entry using MD5", ^{
460 | __block BOOL successReached = NO;
461 | __block BOOL failureReached = NO;
462 | shakingAlertView = [[ShakingAlertView alloc] initWithAlertTitle:title
463 | checkForPassword:MD5Password
464 | usingHashingTechnique:HashTechniqueMD5
465 | onCorrectPassword:^{
466 | successReached = YES;
467 | } onDismissalWithoutPassword:^{
468 | failureReached = YES;
469 | }];
470 | [shakingAlertView show];
471 |
472 | // Type and tap return
473 | // Test the view shakes for the incorrect password
474 | shakingAlertView.passwordField.text = @"incorrect_password";
475 | [[shakingAlertView should] receive:@selector(animateIncorrectPassword)];
476 | [shakingAlertView.delegate alertView:shakingAlertView clickedButtonAtIndex:shakingAlertView.firstOtherButtonIndex];
477 |
478 | // Neither of the completion blocks should have been called
479 | [[theValue(successReached) should] beFalse];
480 | [[theValue(failureReached) should] beFalse];
481 | });
482 |
483 |
484 | });
485 | // context end
486 | // ----------------------------------------------
487 |
488 | });
489 |
490 | SPEC_END
491 |
492 |
493 |
--------------------------------------------------------------------------------
/Example Project/ExampleProject.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | A33909D1160F17D80083C023 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33909D0160F17D80083C023 /* UIKit.framework */; };
11 | A33909D3160F17D80083C023 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33909D2160F17D80083C023 /* Foundation.framework */; };
12 | A33909D5160F17D80083C023 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33909D4160F17D80083C023 /* CoreGraphics.framework */; };
13 | A33909DB160F17D80083C023 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A33909D9160F17D80083C023 /* InfoPlist.strings */; };
14 | A33909DD160F17D80083C023 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A33909DC160F17D80083C023 /* main.m */; };
15 | A33909E1160F17D80083C023 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A33909E0160F17D80083C023 /* AppDelegate.m */; };
16 | A33909E4160F17D80083C023 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A33909E3160F17D80083C023 /* ViewController.m */; };
17 | A33909E7160F17D80083C023 /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = A33909E5160F17D80083C023 /* ViewController_iPhone.xib */; };
18 | A33909EA160F17D80083C023 /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = A33909E8160F17D80083C023 /* ViewController_iPad.xib */; };
19 | A33909F3160F18400083C023 /* ModalViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = A33909F0160F18400083C023 /* ModalViewController_iPhone.xib */; };
20 | A33909F4160F18400083C023 /* ModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A33909F2160F18400083C023 /* ModalViewController.m */; };
21 | A33909F9160F18630083C023 /* ModalViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = A33909F8160F18630083C023 /* ModalViewController_iPad.xib */; };
22 | A36DDF54171AE1C600E8DF1F /* b64.m in Sources */ = {isa = PBXBuildFile; fileRef = A36DDF51171AE1C600E8DF1F /* b64.m */; };
23 | A36DDF55171AE1C600E8DF1F /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = A36DDF53171AE1C600E8DF1F /* NSData+Base64.m */; };
24 | A36DDF58171AE1CE00E8DF1F /* ShakingAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = A36DDF57171AE1CE00E8DF1F /* ShakingAlertView.m */; };
25 | A36DDF5A171AE5D500E8DF1F /* ShakingAlertViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A36DDF59171AE5D500E8DF1F /* ShakingAlertViewTests.m */; };
26 | A3F40CD016D189F900E5FA63 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A3F40CCF16D189F900E5FA63 /* SenTestingKit.framework */; };
27 | A3F40CD116D189F900E5FA63 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33909D0160F17D80083C023 /* UIKit.framework */; };
28 | A3F40CD216D189F900E5FA63 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A33909D2160F17D80083C023 /* Foundation.framework */; };
29 | A3F40CD816D189F900E5FA63 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A3F40CD616D189F900E5FA63 /* InfoPlist.strings */; };
30 | A3F40CE116D18B7500E5FA63 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A3F40CE016D18B7500E5FA63 /* Default-568h@2x.png */; };
31 | F892AEBA08E346208C7BE4F5 /* libPods-ShakingAlertViewKiwiTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DEB572AA6B2D4A51BB4F3488 /* libPods-ShakingAlertViewKiwiTest.a */; };
32 | /* End PBXBuildFile section */
33 |
34 | /* Begin PBXContainerItemProxy section */
35 | A35C738816D198010069D9DF /* PBXContainerItemProxy */ = {
36 | isa = PBXContainerItemProxy;
37 | containerPortal = A33909C3160F17D80083C023 /* Project object */;
38 | proxyType = 1;
39 | remoteGlobalIDString = A33909CB160F17D80083C023;
40 | remoteInfo = ExampleProject;
41 | };
42 | /* End PBXContainerItemProxy section */
43 |
44 | /* Begin PBXFileReference section */
45 | 94B96CAED3054CEE8D07B941 /* Pods-ShakingAlertViewKiwiTest.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShakingAlertViewKiwiTest.xcconfig"; path = "Pods/Pods-ShakingAlertViewKiwiTest.xcconfig"; sourceTree = SOURCE_ROOT; };
46 | A33909CC160F17D80083C023 /* ExampleProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
47 | A33909D0160F17D80083C023 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
48 | A33909D2160F17D80083C023 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
49 | A33909D4160F17D80083C023 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
50 | A33909D8160F17D80083C023 /* ExampleProject-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ExampleProject-Info.plist"; sourceTree = ""; };
51 | A33909DA160F17D80083C023 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
52 | A33909DC160F17D80083C023 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
53 | A33909DE160F17D80083C023 /* ExampleProject-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ExampleProject-Prefix.pch"; sourceTree = ""; };
54 | A33909DF160F17D80083C023 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
55 | A33909E0160F17D80083C023 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
56 | A33909E2160F17D80083C023 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
57 | A33909E3160F17D80083C023 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
58 | A33909E6160F17D80083C023 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; };
59 | A33909E9160F17D80083C023 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; };
60 | A33909F0160F18400083C023 /* ModalViewController_iPhone.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ModalViewController_iPhone.xib; sourceTree = ""; };
61 | A33909F1160F18400083C023 /* ModalViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModalViewController.h; sourceTree = ""; };
62 | A33909F2160F18400083C023 /* ModalViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModalViewController.m; sourceTree = ""; };
63 | A33909F8160F18630083C023 /* ModalViewController_iPad.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ModalViewController_iPad.xib; sourceTree = ""; };
64 | A36DDF50171AE1C600E8DF1F /* b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = b64.h; path = ../../src/b64.h; sourceTree = ""; };
65 | A36DDF51171AE1C600E8DF1F /* b64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = b64.m; path = ../../src/b64.m; sourceTree = ""; };
66 | A36DDF52171AE1C600E8DF1F /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSData+Base64.h"; path = "../../src/NSData+Base64.h"; sourceTree = ""; };
67 | A36DDF53171AE1C600E8DF1F /* NSData+Base64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSData+Base64.m"; path = "../../src/NSData+Base64.m"; sourceTree = ""; };
68 | A36DDF56171AE1CE00E8DF1F /* ShakingAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ShakingAlertView.h; path = ../../src/ShakingAlertView.h; sourceTree = ""; };
69 | A36DDF57171AE1CE00E8DF1F /* ShakingAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ShakingAlertView.m; path = ../../src/ShakingAlertView.m; sourceTree = ""; };
70 | A36DDF59171AE5D500E8DF1F /* ShakingAlertViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShakingAlertViewTests.m; sourceTree = ""; };
71 | A3F40CCE16D189F900E5FA63 /* ShakingAlertViewKiwiTest.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShakingAlertViewKiwiTest.octest; sourceTree = BUILT_PRODUCTS_DIR; };
72 | A3F40CCF16D189F900E5FA63 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
73 | A3F40CD516D189F900E5FA63 /* ShakingAlertViewKiwiTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ShakingAlertViewKiwiTest-Info.plist"; sourceTree = ""; };
74 | A3F40CD716D189F900E5FA63 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
75 | A3F40CDC16D189F900E5FA63 /* ShakingAlertViewKiwiTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ShakingAlertViewKiwiTest-Prefix.pch"; sourceTree = ""; };
76 | A3F40CE016D18B7500E5FA63 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
77 | DEB572AA6B2D4A51BB4F3488 /* libPods-ShakingAlertViewKiwiTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ShakingAlertViewKiwiTest.a"; sourceTree = BUILT_PRODUCTS_DIR; };
78 | /* End PBXFileReference section */
79 |
80 | /* Begin PBXFrameworksBuildPhase section */
81 | A33909C9160F17D80083C023 /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | A33909D1160F17D80083C023 /* UIKit.framework in Frameworks */,
86 | A33909D3160F17D80083C023 /* Foundation.framework in Frameworks */,
87 | A33909D5160F17D80083C023 /* CoreGraphics.framework in Frameworks */,
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | A3F40CCA16D189F900E5FA63 /* Frameworks */ = {
92 | isa = PBXFrameworksBuildPhase;
93 | buildActionMask = 2147483647;
94 | files = (
95 | A3F40CD016D189F900E5FA63 /* SenTestingKit.framework in Frameworks */,
96 | A3F40CD116D189F900E5FA63 /* UIKit.framework in Frameworks */,
97 | A3F40CD216D189F900E5FA63 /* Foundation.framework in Frameworks */,
98 | F892AEBA08E346208C7BE4F5 /* libPods-ShakingAlertViewKiwiTest.a in Frameworks */,
99 | );
100 | runOnlyForDeploymentPostprocessing = 0;
101 | };
102 | /* End PBXFrameworksBuildPhase section */
103 |
104 | /* Begin PBXGroup section */
105 | A33909C1160F17D80083C023 = {
106 | isa = PBXGroup;
107 | children = (
108 | A3F40CE016D18B7500E5FA63 /* Default-568h@2x.png */,
109 | A33909D6160F17D80083C023 /* ExampleProject */,
110 | A3F40CD316D189F900E5FA63 /* ShakingAlertViewKiwiTest */,
111 | A33909CF160F17D80083C023 /* Frameworks */,
112 | A33909CD160F17D80083C023 /* Products */,
113 | 94B96CAED3054CEE8D07B941 /* Pods-ShakingAlertViewKiwiTest.xcconfig */,
114 | );
115 | sourceTree = "";
116 | };
117 | A33909CD160F17D80083C023 /* Products */ = {
118 | isa = PBXGroup;
119 | children = (
120 | A33909CC160F17D80083C023 /* ExampleProject.app */,
121 | A3F40CCE16D189F900E5FA63 /* ShakingAlertViewKiwiTest.octest */,
122 | );
123 | name = Products;
124 | sourceTree = "";
125 | };
126 | A33909CF160F17D80083C023 /* Frameworks */ = {
127 | isa = PBXGroup;
128 | children = (
129 | A33909D0160F17D80083C023 /* UIKit.framework */,
130 | A33909D2160F17D80083C023 /* Foundation.framework */,
131 | A33909D4160F17D80083C023 /* CoreGraphics.framework */,
132 | A3F40CCF16D189F900E5FA63 /* SenTestingKit.framework */,
133 | DEB572AA6B2D4A51BB4F3488 /* libPods-ShakingAlertViewKiwiTest.a */,
134 | );
135 | name = Frameworks;
136 | sourceTree = "";
137 | };
138 | A33909D6160F17D80083C023 /* ExampleProject */ = {
139 | isa = PBXGroup;
140 | children = (
141 | A33909DF160F17D80083C023 /* AppDelegate.h */,
142 | A33909E0160F17D80083C023 /* AppDelegate.m */,
143 | A33909FC160F18990083C023 /* ShakingAlertView */,
144 | A33909FB160F18920083C023 /* View Controllers */,
145 | A33909FA160F18850083C023 /* XIB */,
146 | A33909D7160F17D80083C023 /* Supporting Files */,
147 | );
148 | path = ExampleProject;
149 | sourceTree = "";
150 | };
151 | A33909D7160F17D80083C023 /* Supporting Files */ = {
152 | isa = PBXGroup;
153 | children = (
154 | A33909D8160F17D80083C023 /* ExampleProject-Info.plist */,
155 | A33909D9160F17D80083C023 /* InfoPlist.strings */,
156 | A33909DC160F17D80083C023 /* main.m */,
157 | A33909DE160F17D80083C023 /* ExampleProject-Prefix.pch */,
158 | );
159 | name = "Supporting Files";
160 | sourceTree = "";
161 | };
162 | A33909FA160F18850083C023 /* XIB */ = {
163 | isa = PBXGroup;
164 | children = (
165 | A33909E5160F17D80083C023 /* ViewController_iPhone.xib */,
166 | A33909E8160F17D80083C023 /* ViewController_iPad.xib */,
167 | A33909F0160F18400083C023 /* ModalViewController_iPhone.xib */,
168 | A33909F8160F18630083C023 /* ModalViewController_iPad.xib */,
169 | );
170 | name = XIB;
171 | sourceTree = "";
172 | };
173 | A33909FB160F18920083C023 /* View Controllers */ = {
174 | isa = PBXGroup;
175 | children = (
176 | A33909E2160F17D80083C023 /* ViewController.h */,
177 | A33909E3160F17D80083C023 /* ViewController.m */,
178 | A33909F1160F18400083C023 /* ModalViewController.h */,
179 | A33909F2160F18400083C023 /* ModalViewController.m */,
180 | );
181 | name = "View Controllers";
182 | sourceTree = "";
183 | };
184 | A33909FC160F18990083C023 /* ShakingAlertView */ = {
185 | isa = PBXGroup;
186 | children = (
187 | A36DDF56171AE1CE00E8DF1F /* ShakingAlertView.h */,
188 | A36DDF57171AE1CE00E8DF1F /* ShakingAlertView.m */,
189 | A3E0B6C5160F4555001E7952 /* Crypt */,
190 | );
191 | name = ShakingAlertView;
192 | sourceTree = "";
193 | };
194 | A3E0B6C5160F4555001E7952 /* Crypt */ = {
195 | isa = PBXGroup;
196 | children = (
197 | A36DDF50171AE1C600E8DF1F /* b64.h */,
198 | A36DDF51171AE1C600E8DF1F /* b64.m */,
199 | A36DDF52171AE1C600E8DF1F /* NSData+Base64.h */,
200 | A36DDF53171AE1C600E8DF1F /* NSData+Base64.m */,
201 | );
202 | name = Crypt;
203 | sourceTree = "";
204 | };
205 | A3F40CD316D189F900E5FA63 /* ShakingAlertViewKiwiTest */ = {
206 | isa = PBXGroup;
207 | children = (
208 | A36DDF59171AE5D500E8DF1F /* ShakingAlertViewTests.m */,
209 | A3F40CD416D189F900E5FA63 /* Supporting Files */,
210 | );
211 | path = ShakingAlertViewKiwiTest;
212 | sourceTree = "";
213 | };
214 | A3F40CD416D189F900E5FA63 /* Supporting Files */ = {
215 | isa = PBXGroup;
216 | children = (
217 | A3F40CD516D189F900E5FA63 /* ShakingAlertViewKiwiTest-Info.plist */,
218 | A3F40CD616D189F900E5FA63 /* InfoPlist.strings */,
219 | A3F40CDC16D189F900E5FA63 /* ShakingAlertViewKiwiTest-Prefix.pch */,
220 | );
221 | name = "Supporting Files";
222 | sourceTree = "";
223 | };
224 | /* End PBXGroup section */
225 |
226 | /* Begin PBXNativeTarget section */
227 | A33909CB160F17D80083C023 /* ExampleProject */ = {
228 | isa = PBXNativeTarget;
229 | buildConfigurationList = A33909ED160F17D80083C023 /* Build configuration list for PBXNativeTarget "ExampleProject" */;
230 | buildPhases = (
231 | A33909C8160F17D80083C023 /* Sources */,
232 | A33909C9160F17D80083C023 /* Frameworks */,
233 | A33909CA160F17D80083C023 /* Resources */,
234 | );
235 | buildRules = (
236 | );
237 | dependencies = (
238 | );
239 | name = ExampleProject;
240 | productName = ExampleProject;
241 | productReference = A33909CC160F17D80083C023 /* ExampleProject.app */;
242 | productType = "com.apple.product-type.application";
243 | };
244 | A3F40CCD16D189F900E5FA63 /* ShakingAlertViewKiwiTest */ = {
245 | isa = PBXNativeTarget;
246 | buildConfigurationList = A3F40CDD16D189F900E5FA63 /* Build configuration list for PBXNativeTarget "ShakingAlertViewKiwiTest" */;
247 | buildPhases = (
248 | A3F40CC916D189F900E5FA63 /* Sources */,
249 | A3F40CCA16D189F900E5FA63 /* Frameworks */,
250 | A3F40CCB16D189F900E5FA63 /* Resources */,
251 | A3F40CCC16D189F900E5FA63 /* ShellScript */,
252 | 50CE85E8BB0340788216EDCA /* Copy Pods Resources */,
253 | );
254 | buildRules = (
255 | );
256 | dependencies = (
257 | A35C738916D198010069D9DF /* PBXTargetDependency */,
258 | );
259 | name = ShakingAlertViewKiwiTest;
260 | productName = ShakingAlertViewKiwiTest;
261 | productReference = A3F40CCE16D189F900E5FA63 /* ShakingAlertViewKiwiTest.octest */;
262 | productType = "com.apple.product-type.bundle";
263 | };
264 | /* End PBXNativeTarget section */
265 |
266 | /* Begin PBXProject section */
267 | A33909C3160F17D80083C023 /* Project object */ = {
268 | isa = PBXProject;
269 | attributes = {
270 | LastUpgradeCheck = 0460;
271 | ORGANIZATIONNAME = "Luke Stringer";
272 | };
273 | buildConfigurationList = A33909C6160F17D80083C023 /* Build configuration list for PBXProject "ExampleProject" */;
274 | compatibilityVersion = "Xcode 3.2";
275 | developmentRegion = English;
276 | hasScannedForEncodings = 0;
277 | knownRegions = (
278 | en,
279 | );
280 | mainGroup = A33909C1160F17D80083C023;
281 | productRefGroup = A33909CD160F17D80083C023 /* Products */;
282 | projectDirPath = "";
283 | projectRoot = "";
284 | targets = (
285 | A33909CB160F17D80083C023 /* ExampleProject */,
286 | A3F40CCD16D189F900E5FA63 /* ShakingAlertViewKiwiTest */,
287 | );
288 | };
289 | /* End PBXProject section */
290 |
291 | /* Begin PBXResourcesBuildPhase section */
292 | A33909CA160F17D80083C023 /* Resources */ = {
293 | isa = PBXResourcesBuildPhase;
294 | buildActionMask = 2147483647;
295 | files = (
296 | A33909DB160F17D80083C023 /* InfoPlist.strings in Resources */,
297 | A33909E7160F17D80083C023 /* ViewController_iPhone.xib in Resources */,
298 | A33909EA160F17D80083C023 /* ViewController_iPad.xib in Resources */,
299 | A33909F3160F18400083C023 /* ModalViewController_iPhone.xib in Resources */,
300 | A33909F9160F18630083C023 /* ModalViewController_iPad.xib in Resources */,
301 | A3F40CE116D18B7500E5FA63 /* Default-568h@2x.png in Resources */,
302 | );
303 | runOnlyForDeploymentPostprocessing = 0;
304 | };
305 | A3F40CCB16D189F900E5FA63 /* Resources */ = {
306 | isa = PBXResourcesBuildPhase;
307 | buildActionMask = 2147483647;
308 | files = (
309 | A3F40CD816D189F900E5FA63 /* InfoPlist.strings in Resources */,
310 | );
311 | runOnlyForDeploymentPostprocessing = 0;
312 | };
313 | /* End PBXResourcesBuildPhase section */
314 |
315 | /* Begin PBXShellScriptBuildPhase section */
316 | 50CE85E8BB0340788216EDCA /* Copy Pods Resources */ = {
317 | isa = PBXShellScriptBuildPhase;
318 | buildActionMask = 2147483647;
319 | files = (
320 | );
321 | inputPaths = (
322 | );
323 | name = "Copy Pods Resources";
324 | outputPaths = (
325 | );
326 | runOnlyForDeploymentPostprocessing = 0;
327 | shellPath = /bin/sh;
328 | shellScript = "\"${SRCROOT}/Pods/Pods-ShakingAlertViewKiwiTest-resources.sh\"\n";
329 | };
330 | A3F40CCC16D189F900E5FA63 /* ShellScript */ = {
331 | isa = PBXShellScriptBuildPhase;
332 | buildActionMask = 2147483647;
333 | files = (
334 | );
335 | inputPaths = (
336 | );
337 | outputPaths = (
338 | );
339 | runOnlyForDeploymentPostprocessing = 0;
340 | shellPath = /bin/sh;
341 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
342 | };
343 | /* End PBXShellScriptBuildPhase section */
344 |
345 | /* Begin PBXSourcesBuildPhase section */
346 | A33909C8160F17D80083C023 /* Sources */ = {
347 | isa = PBXSourcesBuildPhase;
348 | buildActionMask = 2147483647;
349 | files = (
350 | A33909DD160F17D80083C023 /* main.m in Sources */,
351 | A33909E1160F17D80083C023 /* AppDelegate.m in Sources */,
352 | A33909E4160F17D80083C023 /* ViewController.m in Sources */,
353 | A33909F4160F18400083C023 /* ModalViewController.m in Sources */,
354 | A36DDF54171AE1C600E8DF1F /* b64.m in Sources */,
355 | A36DDF55171AE1C600E8DF1F /* NSData+Base64.m in Sources */,
356 | A36DDF58171AE1CE00E8DF1F /* ShakingAlertView.m in Sources */,
357 | );
358 | runOnlyForDeploymentPostprocessing = 0;
359 | };
360 | A3F40CC916D189F900E5FA63 /* Sources */ = {
361 | isa = PBXSourcesBuildPhase;
362 | buildActionMask = 2147483647;
363 | files = (
364 | A36DDF5A171AE5D500E8DF1F /* ShakingAlertViewTests.m in Sources */,
365 | );
366 | runOnlyForDeploymentPostprocessing = 0;
367 | };
368 | /* End PBXSourcesBuildPhase section */
369 |
370 | /* Begin PBXTargetDependency section */
371 | A35C738916D198010069D9DF /* PBXTargetDependency */ = {
372 | isa = PBXTargetDependency;
373 | target = A33909CB160F17D80083C023 /* ExampleProject */;
374 | targetProxy = A35C738816D198010069D9DF /* PBXContainerItemProxy */;
375 | };
376 | /* End PBXTargetDependency section */
377 |
378 | /* Begin PBXVariantGroup section */
379 | A33909D9160F17D80083C023 /* InfoPlist.strings */ = {
380 | isa = PBXVariantGroup;
381 | children = (
382 | A33909DA160F17D80083C023 /* en */,
383 | );
384 | name = InfoPlist.strings;
385 | sourceTree = "";
386 | };
387 | A33909E5160F17D80083C023 /* ViewController_iPhone.xib */ = {
388 | isa = PBXVariantGroup;
389 | children = (
390 | A33909E6160F17D80083C023 /* en */,
391 | );
392 | name = ViewController_iPhone.xib;
393 | sourceTree = "";
394 | };
395 | A33909E8160F17D80083C023 /* ViewController_iPad.xib */ = {
396 | isa = PBXVariantGroup;
397 | children = (
398 | A33909E9160F17D80083C023 /* en */,
399 | );
400 | name = ViewController_iPad.xib;
401 | sourceTree = "";
402 | };
403 | A3F40CD616D189F900E5FA63 /* InfoPlist.strings */ = {
404 | isa = PBXVariantGroup;
405 | children = (
406 | A3F40CD716D189F900E5FA63 /* en */,
407 | );
408 | name = InfoPlist.strings;
409 | sourceTree = "";
410 | };
411 | /* End PBXVariantGroup section */
412 |
413 | /* Begin XCBuildConfiguration section */
414 | A33909EB160F17D80083C023 /* Debug */ = {
415 | isa = XCBuildConfiguration;
416 | buildSettings = {
417 | ALWAYS_SEARCH_USER_PATHS = NO;
418 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
420 | CLANG_WARN_CONSTANT_CONVERSION = YES;
421 | CLANG_WARN_ENUM_CONVERSION = YES;
422 | CLANG_WARN_INT_CONVERSION = YES;
423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
425 | COPY_PHASE_STRIP = NO;
426 | GCC_C_LANGUAGE_STANDARD = gnu99;
427 | GCC_DYNAMIC_NO_PIC = NO;
428 | GCC_OPTIMIZATION_LEVEL = 0;
429 | GCC_PREPROCESSOR_DEFINITIONS = (
430 | "DEBUG=1",
431 | "$(inherited)",
432 | );
433 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
434 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
435 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
436 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
437 | GCC_WARN_UNUSED_VARIABLE = YES;
438 | IPHONEOS_DEPLOYMENT_TARGET = 5.1;
439 | SDKROOT = iphoneos;
440 | TARGETED_DEVICE_FAMILY = "1,2";
441 | };
442 | name = Debug;
443 | };
444 | A33909EC160F17D80083C023 /* Release */ = {
445 | isa = XCBuildConfiguration;
446 | buildSettings = {
447 | ALWAYS_SEARCH_USER_PATHS = NO;
448 | ARCHS = "$(ARCHS_STANDARD_32_BIT)";
449 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
450 | CLANG_WARN_CONSTANT_CONVERSION = YES;
451 | CLANG_WARN_ENUM_CONVERSION = YES;
452 | CLANG_WARN_INT_CONVERSION = YES;
453 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
454 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
455 | COPY_PHASE_STRIP = YES;
456 | GCC_C_LANGUAGE_STANDARD = gnu99;
457 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
458 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
459 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
460 | GCC_WARN_UNUSED_VARIABLE = YES;
461 | IPHONEOS_DEPLOYMENT_TARGET = 5.1;
462 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
463 | SDKROOT = iphoneos;
464 | TARGETED_DEVICE_FAMILY = "1,2";
465 | VALIDATE_PRODUCT = YES;
466 | };
467 | name = Release;
468 | };
469 | A33909EE160F17D80083C023 /* Debug */ = {
470 | isa = XCBuildConfiguration;
471 | buildSettings = {
472 | CLANG_ENABLE_OBJC_ARC = YES;
473 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
474 | GCC_PREFIX_HEADER = "ExampleProject/ExampleProject-Prefix.pch";
475 | INFOPLIST_FILE = "ExampleProject/ExampleProject-Info.plist";
476 | PRODUCT_NAME = "$(TARGET_NAME)";
477 | WRAPPER_EXTENSION = app;
478 | };
479 | name = Debug;
480 | };
481 | A33909EF160F17D80083C023 /* Release */ = {
482 | isa = XCBuildConfiguration;
483 | buildSettings = {
484 | CLANG_ENABLE_OBJC_ARC = YES;
485 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
486 | GCC_PREFIX_HEADER = "ExampleProject/ExampleProject-Prefix.pch";
487 | INFOPLIST_FILE = "ExampleProject/ExampleProject-Info.plist";
488 | PRODUCT_NAME = "$(TARGET_NAME)";
489 | WRAPPER_EXTENSION = app;
490 | };
491 | name = Release;
492 | };
493 | A3F40CDE16D189F900E5FA63 /* Debug */ = {
494 | isa = XCBuildConfiguration;
495 | baseConfigurationReference = 94B96CAED3054CEE8D07B941 /* Pods-ShakingAlertViewKiwiTest.xcconfig */;
496 | buildSettings = {
497 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleProject.app/ExampleProject";
498 | CLANG_CXX_LIBRARY = "libc++";
499 | CLANG_ENABLE_OBJC_ARC = YES;
500 | CLANG_WARN_CONSTANT_CONVERSION = YES;
501 | CLANG_WARN_EMPTY_BODY = YES;
502 | CLANG_WARN_ENUM_CONVERSION = YES;
503 | CLANG_WARN_INT_CONVERSION = YES;
504 | FRAMEWORK_SEARCH_PATHS = (
505 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
506 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
507 | );
508 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
509 | GCC_PREFIX_HEADER = "ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Prefix.pch";
510 | INFOPLIST_FILE = "ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Info.plist";
511 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
512 | ONLY_ACTIVE_ARCH = YES;
513 | PRODUCT_NAME = "$(TARGET_NAME)";
514 | TEST_HOST = "$(BUNDLE_LOADER)";
515 | WRAPPER_EXTENSION = octest;
516 | };
517 | name = Debug;
518 | };
519 | A3F40CDF16D189F900E5FA63 /* Release */ = {
520 | isa = XCBuildConfiguration;
521 | baseConfigurationReference = 94B96CAED3054CEE8D07B941 /* Pods-ShakingAlertViewKiwiTest.xcconfig */;
522 | buildSettings = {
523 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ExampleProject.app/ExampleProject";
524 | CLANG_CXX_LIBRARY = "libc++";
525 | CLANG_ENABLE_OBJC_ARC = YES;
526 | CLANG_WARN_CONSTANT_CONVERSION = YES;
527 | CLANG_WARN_EMPTY_BODY = YES;
528 | CLANG_WARN_ENUM_CONVERSION = YES;
529 | CLANG_WARN_INT_CONVERSION = YES;
530 | FRAMEWORK_SEARCH_PATHS = (
531 | "\"$(SDKROOT)/Developer/Library/Frameworks\"",
532 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
533 | );
534 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
535 | GCC_PREFIX_HEADER = "ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Prefix.pch";
536 | INFOPLIST_FILE = "ShakingAlertViewKiwiTest/ShakingAlertViewKiwiTest-Info.plist";
537 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
538 | PRODUCT_NAME = "$(TARGET_NAME)";
539 | TEST_HOST = "$(BUNDLE_LOADER)";
540 | WRAPPER_EXTENSION = octest;
541 | };
542 | name = Release;
543 | };
544 | /* End XCBuildConfiguration section */
545 |
546 | /* Begin XCConfigurationList section */
547 | A33909C6160F17D80083C023 /* Build configuration list for PBXProject "ExampleProject" */ = {
548 | isa = XCConfigurationList;
549 | buildConfigurations = (
550 | A33909EB160F17D80083C023 /* Debug */,
551 | A33909EC160F17D80083C023 /* Release */,
552 | );
553 | defaultConfigurationIsVisible = 0;
554 | defaultConfigurationName = Release;
555 | };
556 | A33909ED160F17D80083C023 /* Build configuration list for PBXNativeTarget "ExampleProject" */ = {
557 | isa = XCConfigurationList;
558 | buildConfigurations = (
559 | A33909EE160F17D80083C023 /* Debug */,
560 | A33909EF160F17D80083C023 /* Release */,
561 | );
562 | defaultConfigurationIsVisible = 0;
563 | defaultConfigurationName = Release;
564 | };
565 | A3F40CDD16D189F900E5FA63 /* Build configuration list for PBXNativeTarget "ShakingAlertViewKiwiTest" */ = {
566 | isa = XCConfigurationList;
567 | buildConfigurations = (
568 | A3F40CDE16D189F900E5FA63 /* Debug */,
569 | A3F40CDF16D189F900E5FA63 /* Release */,
570 | );
571 | defaultConfigurationIsVisible = 0;
572 | defaultConfigurationName = Release;
573 | };
574 | /* End XCConfigurationList section */
575 | };
576 | rootObject = A33909C3160F17D80083C023 /* Project object */;
577 | }
578 |
--------------------------------------------------------------------------------