├── .gitignore
├── 2011 Fall
├── Calculator
│ ├── Calculator.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ ├── Calculator
│ │ ├── Calculator-Info.plist
│ │ ├── Calculator-Prefix.pch
│ │ ├── CalculatorAlgorithmRPN.h
│ │ ├── CalculatorAlgorithmRPN.m
│ │ ├── CalculatorAppDelegate.h
│ │ ├── CalculatorAppDelegate.m
│ │ ├── CalculatorViewController.h
│ │ ├── CalculatorViewController.m
│ │ ├── en.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainStoryboard.storyboard
│ │ └── main.m
│ └── Screen Shot 2013-08-27 at 19.03.57.png
└── Happiness
│ ├── Happiness.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── Happiness
│ ├── FaceView.h
│ ├── FaceView.m
│ ├── Happiness-Info.plist
│ ├── Happiness-Prefix.pch
│ ├── HappinessAppDelegate.h
│ ├── HappinessAppDelegate.m
│ ├── HappinessViewController.h
│ ├── HappinessViewController.m
│ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── MainStoryboard.storyboard
│ └── main.m
│ └── Screen Shot 2013-08-27 at 19.06.13.png
├── 2013 Winter
├── Attribute
│ ├── Attribute.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Attribute
│ │ ├── Attribute-Info.plist
│ │ ├── Attribute-Prefix.pch
│ │ ├── AttributeAppDelegate.h
│ │ ├── AttributeAppDelegate.m
│ │ ├── AttributeViewController.h
│ │ ├── AttributeViewController.m
│ │ ├── Default-568h@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── MainStoryboard.storyboard
│ │ └── main.m
├── CardViewer
│ ├── CardViewer.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── CardViewer
│ │ ├── CardChooserAppDelegate.h
│ │ ├── CardChooserAppDelegate.m
│ │ ├── CardChooserViewController.h
│ │ ├── CardChooserViewController.m
│ │ ├── CardDisplayViewController.h
│ │ ├── CardDisplayViewController.m
│ │ ├── CardViewer-Info.plist
│ │ ├── CardViewer-Prefix.pch
│ │ ├── Default-568h@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ ├── Face Card Images
│ │ ├── J♠.jpg
│ │ ├── J♠@2x.jpg
│ │ ├── J♣.jpg
│ │ ├── J♣@2x.jpg
│ │ ├── J♥.jpg
│ │ ├── J♥@2x.jpg
│ │ ├── J♦.jpg
│ │ ├── J♦@2x.jpg
│ │ ├── K♠.jpg
│ │ ├── K♠@2x.jpg
│ │ ├── K♣.jpg
│ │ ├── K♣@2x.jpg
│ │ ├── K♥.jpg
│ │ ├── K♥@2x.jpg
│ │ ├── K♦.jpg
│ │ ├── K♦@2x.jpg
│ │ ├── Q♠.jpg
│ │ ├── Q♠@2x.jpg
│ │ ├── Q♣.jpg
│ │ ├── Q♣@2x.jpg
│ │ ├── Q♥.jpg
│ │ ├── Q♥@2x.jpg
│ │ ├── Q♦.jpg
│ │ └── Q♦@2x.jpg
│ │ ├── PlayingCardView.h
│ │ ├── PlayingCardView.m
│ │ ├── cardback.png
│ │ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── MainStoryboard.storyboard
│ │ └── main.m
├── Matchismo
│ ├── Matchismo Tests
│ │ ├── BaseCardTests.m
│ │ ├── BaseDeckTests.m
│ │ ├── GcovTestObserver.m
│ │ ├── Matchismo Tests-Info.plist
│ │ ├── Matchismo Tests-Prefix.pch
│ │ ├── PlayingCardTests.m
│ │ ├── PlayingDeckTests.m
│ │ ├── PlayingGameTests.m
│ │ ├── SetCardTests.m
│ │ ├── SetDeckTests.m
│ │ ├── SetGameTests.m
│ │ └── en.lproj
│ │ │ └── InfoPlist.strings
│ ├── Matchismo.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ ├── Matchismo
│ │ ├── Abstract.h
│ │ ├── CardGameAppDelegate.h
│ │ ├── CardGameAppDelegate.m
│ │ ├── Components
│ │ │ ├── Card.h
│ │ │ ├── Card.m
│ │ │ ├── Deck.h
│ │ │ ├── Deck.m
│ │ │ ├── PlayResult.h
│ │ │ ├── PlayResult.m
│ │ │ ├── PlayingCard.h
│ │ │ ├── PlayingCard.m
│ │ │ ├── PlayingDeck.h
│ │ │ ├── PlayingDeck.m
│ │ │ ├── PlayingGame.h
│ │ │ ├── PlayingGame.m
│ │ │ ├── SetCard.h
│ │ │ ├── SetCard.m
│ │ │ ├── SetDeck.h
│ │ │ ├── SetDeck.m
│ │ │ ├── SetGame.h
│ │ │ └── SetGame.m
│ │ ├── Controllers
│ │ │ ├── CardGameViewController.h
│ │ │ ├── CardGameViewController.m
│ │ │ ├── GameResult.h
│ │ │ ├── GameResult.m
│ │ │ ├── GameResultViewController.h
│ │ │ ├── GameResultViewController.m
│ │ │ ├── SetGameViewController.h
│ │ │ └── SetGameViewController.m
│ │ ├── Debug.xcconfig
│ │ ├── Matchismo-Info.plist
│ │ ├── Matchismo-Prefix.pch
│ │ ├── Resources
│ │ │ └── Images.xcassets
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ │ ├── LaunchImage.launchimage
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Default-568h@2x-1.png
│ │ │ │ ├── Default-568h@2x.png
│ │ │ │ ├── Default.png
│ │ │ │ ├── Default@2x-1.png
│ │ │ │ └── Default@2x.png
│ │ │ │ ├── Tab Bar
│ │ │ │ ├── hash.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── hash.png
│ │ │ │ ├── set.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── set.png
│ │ │ │ └── spade.imageset
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── spade.png
│ │ │ │ └── cardback.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── cardback.png
│ │ │ │ └── cardback@2x.png
│ │ ├── Warnings.xcconfig
│ │ ├── en.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── MainStoryboard.storyboard
│ │ └── main.m
│ ├── Screen Shot 2013-08-27 at 18.49.06.png
│ ├── Screen Shot 2013-09-25 at 14.11.19.png
│ └── TODO.h
├── SPoT
│ ├── README.md
│ ├── SPoT.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ ├── SPoT
│ │ ├── Adapters
│ │ │ ├── Controllers
│ │ │ │ ├── ImageDetailViewController.h
│ │ │ │ ├── ImageDetailViewController.m
│ │ │ │ ├── ImageListViewController.h
│ │ │ │ ├── ImageListViewController.m
│ │ │ │ ├── TabletSplitViewController.h
│ │ │ │ ├── TabletSplitViewController.m
│ │ │ │ ├── TagListViewController.h
│ │ │ │ └── TagListViewController.m
│ │ │ └── Gateways
│ │ │ │ ├── ImageSupplierFlickr.h
│ │ │ │ ├── ImageSupplierFlickr.m
│ │ │ │ ├── ImageSupplierGateway.h
│ │ │ │ └── ImageSupplierGateway.m
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Entities
│ │ │ ├── ImageEntity.h
│ │ │ ├── ImageEntity.m
│ │ │ ├── ImageFormatURLs.h
│ │ │ ├── ImageFormatURLs.m
│ │ │ ├── TagEntity.h
│ │ │ └── TagEntity.m
│ │ ├── Interfaces
│ │ │ ├── FlickrFetcher
│ │ │ │ ├── FlickrAPIKey.h
│ │ │ │ ├── FlickrFetcher.h
│ │ │ │ └── FlickrFetcher.m
│ │ │ ├── Resources
│ │ │ │ └── Images.xcassets
│ │ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ │ │ └── LaunchImage.launchimage
│ │ │ │ │ └── Contents.json
│ │ │ └── Screens
│ │ │ │ ├── iPadPhotoBrowsing.storyboard
│ │ │ │ └── iPhonePhotoBrowsing.storyboard
│ │ ├── SPoT-Info.plist
│ │ ├── SPoT-Prefix.pch
│ │ ├── Support
│ │ │ ├── Config
│ │ │ │ ├── Debug.xcconfig
│ │ │ │ └── Warnings.xcconfig
│ │ │ └── Helpers
│ │ │ │ ├── ArrayCount.h
│ │ │ │ └── Helpers.h
│ │ ├── Use Cases
│ │ │ ├── ImageSupplierDataSource.h
│ │ │ ├── ImageViewingInteractor.h
│ │ │ ├── ImageViewingInteractor.m
│ │ │ ├── TagListingInteractor.h
│ │ │ └── TagListingInteractor.m
│ │ ├── en.lproj
│ │ │ └── InfoPlist.strings
│ │ └── main.m
│ └── SPoTTests
│ │ ├── FlickrFetcherLearningTests.m
│ │ ├── SPoTTests-Info.plist
│ │ ├── SPoTTests.m
│ │ └── en.lproj
│ │ └── InfoPlist.strings
├── Shutterbug
│ ├── Shutterbug.xcodeproj
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── Shutterbug
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Default-568h@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ ├── FlickrFetcher
│ │ ├── FlickrAPIKey.h
│ │ ├── FlickrFetcher.h
│ │ └── FlickrFetcher.m
│ │ ├── FlickrPhotoTVC.h
│ │ ├── FlickrPhotoTVC.m
│ │ ├── HawaiiImageViewController.h
│ │ ├── HawaiiImageViewController.m
│ │ ├── ImageViewController.h
│ │ ├── ImageViewController.m
│ │ ├── LatestFlickrPhotosTVC.h
│ │ ├── LatestFlickrPhotosTVC.m
│ │ ├── Shutterbug-Info.plist
│ │ ├── Shutterbug-Prefix.pch
│ │ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── MainStoryboard.storyboard
│ │ └── main.m
└── SuperCard
│ ├── SuperCard.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── SuperCard
│ ├── Base.lproj
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Face Cards
│ │ │ ├── J♠.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── J♠.png
│ │ │ │ └── J♠@2x.png
│ │ │ ├── J♣.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── J♣.png
│ │ │ │ └── J♣@2x.png
│ │ │ ├── J♥.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── J♥.png
│ │ │ │ └── J♥@2x.png
│ │ │ ├── J♦.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── J♦.png
│ │ │ │ └── J♦@2x.png
│ │ │ ├── K♠.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── K♠.png
│ │ │ │ └── K♠@2x.png
│ │ │ ├── K♣.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── K♣.png
│ │ │ │ └── K♣@2x.png
│ │ │ ├── K♥.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── K♥.png
│ │ │ │ └── K♥@2x.png
│ │ │ ├── K♦.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── K♦.png
│ │ │ │ └── K♦@2x.png
│ │ │ ├── Q♠.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Q♠.png
│ │ │ │ └── Q♠@2x.png
│ │ │ ├── Q♣.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Q♣.png
│ │ │ │ └── Q♣@2x.png
│ │ │ ├── Q♥.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Q♥.png
│ │ │ │ └── Q♥@2x.png
│ │ │ └── Q♦.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── Q♦.png
│ │ │ │ └── Q♦@2x.png
│ │ ├── LaunchImage.launchimage
│ │ │ └── Contents.json
│ │ └── cardback.imageset
│ │ │ ├── Contents.json
│ │ │ └── cardback.png
│ ├── PlayingCardView.h
│ ├── PlayingCardView.m
│ ├── SuperCard-Info.plist
│ ├── SuperCard-Prefix.pch
│ ├── SuperCardAppDelegate.h
│ ├── SuperCardAppDelegate.m
│ ├── SuperCardViewController.h
│ ├── SuperCardViewController.m
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ └── main.m
│ └── SuperCardTests
│ ├── SuperCardTests-Info.plist
│ ├── SuperCardTests.m
│ └── en.lproj
│ └── InfoPlist.strings
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # https://raw.github.com/github/gitignore/master/Objective-C.gitignore
2 | # Xcode
3 | .DS_Store
4 | */build/*
5 | *.pbxuser
6 | !default.pbxuser
7 | *.mode1v3
8 | !default.mode1v3
9 | *.mode2v3
10 | !default.mode2v3
11 | *.perspectivev3
12 | !default.perspectivev3
13 | xcuserdata
14 | profile
15 | *.moved-aside
16 | DerivedData
17 | .idea/
18 | *.hmap
19 | *.xccheckout
20 |
21 | #CocoaPods
22 | Pods
23 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/Calculator-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | pt.mindclick.cs193p.${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 | UIMainStoryboardFile
28 | MainStoryboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/Calculator-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Calculator' target in the 'Calculator' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/CalculatorAlgorithmRPN.h:
--------------------------------------------------------------------------------
1 | //
2 | // CalculatorAlgorithmRPN.h
3 | // Calculator
4 | //
5 | // Created by Hugo Ferreira on 2012/07/05.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CalculatorAlgorithmRPN : NSObject
12 |
13 | - (void)pushOperand:(double)operand;
14 | - (void)pushVariable:(NSString *)variable;
15 | - (void)pushOperation:(NSString *)operation;
16 | - (void)clearStack;
17 | - (void)clearTopOfStack;
18 |
19 | @property (readonly) id program;
20 |
21 | + (id)runProgram:(id)program;
22 | + (id)runProgram:(id)program usingVariableValues:(NSDictionary *)variableValues;
23 | + (NSString *)descriptionOfProgram:(id)program;
24 | + (NSSet *)variablesUsedInProgram:(id)program;
25 | + (BOOL)isVariable:(NSString *)element;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/CalculatorAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // CalculatorAppDelegate.h
3 | // Calculator
4 | //
5 | // Created by Hugo Ferreira on 2012/07/05.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CalculatorAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/CalculatorAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // CalculatorAppDelegate.m
3 | // Calculator
4 | //
5 | // Created by Hugo Ferreira on 2012/07/05.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "CalculatorAppDelegate.h"
10 |
11 | @implementation CalculatorAppDelegate
12 |
13 | @synthesize window = _window;
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | // Override point for customization after application launch.
18 | return YES;
19 | }
20 |
21 | - (void)applicationWillResignActive:(UIApplication *)application
22 | {
23 | // 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.
24 | // 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.
25 | }
26 |
27 | - (void)applicationDidEnterBackground:(UIApplication *)application
28 | {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application
34 | {
35 | // 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.
36 | }
37 |
38 | - (void)applicationDidBecomeActive:(UIApplication *)application
39 | {
40 | // 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.
41 | }
42 |
43 | - (void)applicationWillTerminate:(UIApplication *)application
44 | {
45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/CalculatorViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CalculatorViewController.h
3 | // Calculator
4 | //
5 | // Created by Hugo Ferreira on 2012/07/05.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CalculatorViewController : UIViewController
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *display;
14 | @property (weak, nonatomic) IBOutlet UILabel *history;
15 | @property (weak, nonatomic) IBOutlet UILabel *variables;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Calculator/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Calculator
4 | //
5 | // Created by Hugo Ferreira on 2012/07/05.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "CalculatorAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CalculatorAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2011 Fall/Calculator/Screen Shot 2013-08-27 at 19.03.57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2011 Fall/Calculator/Screen Shot 2013-08-27 at 19.03.57.png
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/FaceView.h:
--------------------------------------------------------------------------------
1 | //
2 | // FaceView.h
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class FaceView;
12 |
13 | @protocol FaceViewDataSource
14 |
15 | - (float)smileForFaceView:(FaceView *)sender;
16 |
17 | @end
18 |
19 | @interface FaceView : UIView
20 |
21 | @property (nonatomic) CGFloat scale;
22 | @property (nonatomic, weak) IBOutlet id dataSource;
23 |
24 | - (void)pinch:(UIPinchGestureRecognizer *)gesture;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/FaceView.m:
--------------------------------------------------------------------------------
1 | //
2 | // FaceView.m
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "FaceView.h"
10 |
11 | #define FACE_SIZE_FACTOR 0.90
12 | #define EYES_SIZE_FACTOR 0.10
13 | #define EYES_POSITION_H 0.35
14 | #define EYES_POSITION_V 0.35
15 | #define MOUTH_SIZE_FACTOR 0.25
16 | #define MOUTH_POSITION_H 0.45
17 | #define MOUTH_POSITION_V 0.40
18 |
19 | @implementation FaceView
20 |
21 | @synthesize scale = _scale;
22 | @synthesize dataSource = _dataSource;
23 |
24 | - (CGFloat)scale
25 | {
26 | if (!_scale) {
27 | return FACE_SIZE_FACTOR;
28 | } else {
29 | return _scale;
30 | }
31 | }
32 |
33 | - (void)setScale:(CGFloat)scale
34 | {
35 | if (_scale != scale) {
36 | _scale = scale;
37 | [self setNeedsDisplay];
38 | }
39 | }
40 |
41 | - (void)pinch:(UIPinchGestureRecognizer *)gesture
42 | {
43 | if (gesture.state == UIGestureRecognizerStateChanged
44 | || gesture.scale == UIGestureRecognizerStateEnded)
45 | {
46 | self.scale *= gesture.scale;
47 | gesture.scale = 1.0;
48 | }
49 | }
50 |
51 | - (void)setup
52 | {
53 | self.contentMode = UIViewContentModeRedraw;
54 | }
55 |
56 | - (void)awakeFromNib
57 | {
58 | [self setup];
59 | }
60 |
61 | - (id)initWithFrame:(CGRect)frame
62 | {
63 | self = [super initWithFrame:frame];
64 | if (self) {
65 | [self setup];
66 | }
67 | return self;
68 | }
69 |
70 | - (void)drawCircleAtPoint:(CGPoint)center withRadius:(CGFloat)radius inContext:(CGContextRef) context
71 | {
72 | UIGraphicsPushContext(context);
73 | CGContextBeginPath(context);
74 | CGContextAddArc(context, center.x, center.y, radius, 0, 2 * M_PI, YES);
75 | CGContextStrokePath(context);
76 | UIGraphicsPopContext();
77 | }
78 |
79 | - (void)drawRect:(CGRect)rect
80 | {
81 | CGContextRef context = UIGraphicsGetCurrentContext();
82 |
83 | //
84 | // Face...
85 | //
86 | CGPoint midPoint;
87 | midPoint.x = self.bounds.origin.x + self.bounds.size.width / 2;
88 | midPoint.y = self.bounds.origin.y + self.bounds.size.height / 2;
89 |
90 | CGFloat size = ((self.bounds.size.width < self.bounds.size.height)? self.bounds.size.width : self.bounds.size.height) / 2;
91 | size *= self.scale;
92 |
93 | CGContextSetLineWidth(context, 5.0);
94 | [[UIColor blueColor] setStroke];
95 | [self drawCircleAtPoint:midPoint withRadius:size inContext:context];
96 |
97 | //
98 | // Eyes...
99 | //
100 | CGPoint eyePoint;
101 | eyePoint.x = midPoint.x - size * EYES_POSITION_H;
102 | eyePoint.y = midPoint.y - size * EYES_POSITION_V;
103 | [self drawCircleAtPoint:eyePoint withRadius:size * EYES_SIZE_FACTOR inContext:context];
104 |
105 | eyePoint.x = midPoint.x + size * EYES_POSITION_H;
106 | [self drawCircleAtPoint:eyePoint withRadius:size * EYES_SIZE_FACTOR inContext:context];
107 |
108 | //
109 | // Mouth...
110 | //
111 | CGPoint mouthStart;
112 | mouthStart.x = midPoint.x - size * MOUTH_POSITION_H;
113 | mouthStart.y = midPoint.y + size * MOUTH_POSITION_V;
114 | CGPoint mouthStop = mouthStart;
115 | CGPoint mouthCP1 = mouthStart;
116 | CGPoint mouthCP2 = mouthStart;
117 | mouthStop.x = midPoint.x + size * MOUTH_POSITION_H;
118 | mouthCP1.x = midPoint.x - size * MOUTH_POSITION_H / 3;
119 | mouthCP2.x = midPoint.x + size * MOUTH_POSITION_H / 3;
120 |
121 | // Direction: Happy or Smile?
122 | float smileDirection = [self.dataSource smileForFaceView:self];
123 | if (smileDirection <= -1) smileDirection = -1;
124 | if (smileDirection >= 1) smileDirection = 1;
125 |
126 | CGFloat smileOffset = size * MOUTH_SIZE_FACTOR * smileDirection;
127 | mouthCP1.y += smileOffset;
128 | mouthCP2.y += smileOffset;
129 |
130 | CGContextBeginPath(context);
131 | CGContextMoveToPoint(context, mouthStart.x, mouthStart.y);
132 | CGContextAddCurveToPoint(context, mouthCP1.x, mouthCP1.y, mouthCP2.x, mouthCP2.y, mouthStop.x, mouthStop.y);
133 | CGContextStrokePath(context);
134 | }
135 |
136 | @end
137 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/Happiness-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | pt.mindclick.cs193p.${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 | UIMainStoryboardFile
28 | MainStoryboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/Happiness-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Happiness' target in the 'Happiness' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/HappinessAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // HappinessAppDelegate.h
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HappinessAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/HappinessAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // HappinessAppDelegate.m
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "HappinessAppDelegate.h"
10 |
11 | @implementation HappinessAppDelegate
12 |
13 | @synthesize window = _window;
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | // Override point for customization after application launch.
18 | return YES;
19 | }
20 |
21 | - (void)applicationWillResignActive:(UIApplication *)application
22 | {
23 | // 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.
24 | // 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.
25 | }
26 |
27 | - (void)applicationDidEnterBackground:(UIApplication *)application
28 | {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application
34 | {
35 | // 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.
36 | }
37 |
38 | - (void)applicationDidBecomeActive:(UIApplication *)application
39 | {
40 | // 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.
41 | }
42 |
43 | - (void)applicationWillTerminate:(UIApplication *)application
44 | {
45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/HappinessViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HappinessViewController.h
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HappinessViewController : UIViewController
12 |
13 | @property (nonatomic) int happiness; // [sad] 0..100 [happy]
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/HappinessViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HappinessViewController.m
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "HappinessViewController.h"
10 | #import "FaceView.h"
11 |
12 | @interface HappinessViewController ()
13 |
14 | @property (nonatomic, weak) IBOutlet FaceView *faceView;
15 |
16 | @end
17 |
18 | @implementation HappinessViewController
19 |
20 | @synthesize happiness = _happiness;
21 | @synthesize faceView = _faceView;
22 |
23 | - (void)setHappiness:(int)happiness
24 | {
25 | _happiness = happiness;
26 | [self.faceView setNeedsDisplay];
27 | }
28 |
29 | #pragma mark - XPTO
30 |
31 | // TODO xpto
32 |
33 | - (void)setFaceView:(FaceView *)faceView
34 | {
35 | _faceView = faceView;
36 | [self.faceView addGestureRecognizer:[[UIPinchGestureRecognizer alloc] initWithTarget:faceView action:@selector(pinch:)]];
37 | [self.faceView addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleHappiness:)]];
38 | self.faceView.dataSource = self;
39 | }
40 |
41 | - (void)handleHappiness:(UIPanGestureRecognizer *)gesture
42 | {
43 | if (gesture.state == UIGestureRecognizerStateChanged
44 | || gesture.state == UIGestureRecognizerStateEnded)
45 | {
46 | CGPoint translation = [gesture translationInView:self.faceView];
47 | self.happiness -= translation.y / 2;
48 | [gesture setTranslation:CGPointZero inView:self.faceView];
49 | }
50 | }
51 |
52 | - (float)smileForFaceView:(FaceView *)sender
53 | {
54 | return (self.happiness - 50) / 50.0;
55 | }
56 |
57 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
58 | {
59 | return YES;
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/en.lproj/MainStoryboard.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Happiness/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Happiness
4 | //
5 | // Created by Hugo Ferreira on 2012/07/19.
6 | // Copyright (c) 2012 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HappinessAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([HappinessAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2011 Fall/Happiness/Screen Shot 2013-08-27 at 19.06.13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2011 Fall/Happiness/Screen Shot 2013-08-27 at 19.06.13.png
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/Attribute-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | edu.stanford.cs193p.instructor.${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 | UIMainStoryboardFile
28 | MainStoryboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/Attribute-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Attribute' target in the 'Attribute' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/AttributeAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AttributeAppDelegate.h
3 | // Attribute
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AttributeAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/AttributeAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AttributeAppDelegate.m
3 | // Attribute
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "AttributeAppDelegate.h"
10 |
11 | @implementation AttributeAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // 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.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // 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.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/AttributeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AttributeViewController.h
3 | // Attribute
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AttributeViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Attribute/Attribute/Default-568h@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Attribute/Attribute/Default.png
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Attribute/Attribute/Default@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/Attribute/Attribute/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Attribute
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AttributeAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AttributeAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardChooserAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // CardChooserAppDelegate.h
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CardChooserAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardChooserAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // CardChooserAppDelegate.m
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "CardChooserAppDelegate.h"
10 |
11 | @implementation CardChooserAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // 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.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // 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.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardChooserViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CardChooserViewController.h
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CardChooserViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardChooserViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CardChooserViewController.m
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "CardChooserViewController.h"
10 | #import "CardDisplayViewController.h"
11 |
12 | @interface CardChooserViewController ()
13 | @property (weak, nonatomic) IBOutlet UILabel *rankLabel;
14 | @property (weak, nonatomic) IBOutlet UISegmentedControl *suitSegmentedControl;
15 | @property (nonatomic) NSUInteger rank;
16 | @property (nonatomic, readonly) NSString *suit;
17 | @end
18 |
19 | @implementation CardChooserViewController
20 |
21 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
22 | {
23 | if ([segue.identifier isEqualToString:@"ShowCard"]) {
24 | if ([segue.destinationViewController isKindOfClass:[CardDisplayViewController class]]) {
25 | CardDisplayViewController *cdvc = (CardDisplayViewController *)segue.destinationViewController;
26 | cdvc.suit = self.suit;
27 | cdvc.rank = self.rank;
28 | cdvc.title = [[self rankAsString] stringByAppendingString:self.suit];
29 | }
30 | }
31 | }
32 |
33 | - (NSString *)rankAsString
34 | {
35 | return @[@"?",@"A",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"J",@"Q",@"K"][self.rank];
36 | }
37 |
38 | - (void)setRank:(NSUInteger)rank
39 | {
40 | _rank = rank;
41 | self.rankLabel.text = [self rankAsString];
42 | }
43 |
44 | - (NSString *)suit
45 | {
46 | return [self.suitSegmentedControl titleForSegmentAtIndex:self.suitSegmentedControl.selectedSegmentIndex];
47 | }
48 |
49 | - (IBAction)changeRank:(UISlider *)sender
50 | {
51 | self.rank = round(sender.value);
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardDisplayViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CardDisplayViewController.h
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CardDisplayViewController : UIViewController
12 |
13 | @property (nonatomic) NSUInteger rank;
14 | @property (nonatomic, strong) NSString *suit;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardDisplayViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CardDisplayViewController.m
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "CardDisplayViewController.h"
10 | #import "PlayingCardView.h"
11 |
12 | @interface CardDisplayViewController ()
13 | @property (weak, nonatomic) IBOutlet PlayingCardView *playingCardView;
14 | @end
15 |
16 | @implementation CardDisplayViewController
17 |
18 | - (void)viewWillAppear:(BOOL)animated
19 | {
20 | [super viewWillAppear:animated];
21 | self.playingCardView.rank = self.rank;
22 | self.playingCardView.suit = self.suit;
23 | self.playingCardView.faceUp = YES;
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardViewer-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | edu.stanford.cs193p.instructor.${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 | UIMainStoryboardFile
28 | MainStoryboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/CardViewer-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'CardViewer' target in the 'CardViewer' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Default-568h@2x.png
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Default.png
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Default@2x.png
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♠.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♠.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♠@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♠@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♣.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♣.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♣@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♣@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♥.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♥.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♥@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♥@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♦.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♦.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/J♦@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/J♦@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♠.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♠.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♠@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♠@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♣.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♣.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♣@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♣@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♥.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♥.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♥@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♥@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♦.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♦.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/K♦@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/K♦@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♠.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♠.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♠@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♠@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♣.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♣.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♣@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♣@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♥.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♥.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♥@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♥@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♦.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♦.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♦@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/Face Card Images/Q♦@2x.jpg
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/PlayingCardView.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingCardView.h
3 | // SuperCard
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PlayingCardView : UIView
12 |
13 | @property (nonatomic) NSUInteger rank;
14 | @property (strong, nonatomic) NSString *suit;
15 |
16 | @property (nonatomic) BOOL faceUp;
17 |
18 | - (void)pinch:(UIPinchGestureRecognizer *)gesture;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/cardback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/CardViewer/CardViewer/cardback.png
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/CardViewer/CardViewer/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CardViewer
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "CardChooserAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CardChooserAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/BaseCardTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseCardTests.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/10/17.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Card.h"
11 |
12 | #pragma mark - Test Support
13 |
14 | @interface BaseCardTests_CardSubclass : Card
15 | @end
16 |
17 | @implementation BaseCardTests_CardSubclass
18 | @end
19 |
20 | #pragma mark - Test Suite
21 |
22 |
23 | @interface BaseCardTests : XCTestCase
24 |
25 | @end
26 |
27 | @implementation BaseCardTests
28 |
29 | - (void)testCannotInstantiateBaseClass
30 | {
31 | XCTAssertThrows([[Card alloc] init]);
32 | }
33 |
34 | - (void)testCannotInvokeAbstractMethods
35 | {
36 | BaseCardTests_CardSubclass *card = [[BaseCardTests_CardSubclass alloc] init];
37 | XCTAssertThrows([card match:@[]]);
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/BaseDeckTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // BaseDeckTests.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/10/17.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Deck.h"
11 | #import "Card.h"
12 |
13 | #pragma mark - Test Support
14 |
15 | @interface BaseDeckTests_CardSubclass : Card
16 | @end
17 |
18 | @implementation BaseDeckTests_CardSubclass
19 | @end
20 |
21 | #pragma mark -
22 |
23 | @interface Deck (Tests)
24 | - (NSMutableArray *)cards;
25 | @end
26 |
27 | #pragma mark - Test Suite
28 |
29 | @interface BaseDeckTests : XCTestCase
30 |
31 | @end
32 |
33 | @implementation BaseDeckTests
34 |
35 | #pragma mark - Helpers
36 |
37 | - (void)createCards:(NSUInteger)howMany inDeck:(Deck *)deck
38 | {
39 | for (NSUInteger i = 0; i < howMany; i++) {
40 | Card *card = [[BaseDeckTests_CardSubclass alloc] init];
41 | [deck addCard:card atTop:NO];
42 | }
43 | }
44 |
45 | - (void)drawAllCardsInDeck:(Deck *)deck
46 | {
47 | NSUInteger numberOfCards = [deck.cards count];
48 | for (NSUInteger i = 0; i < numberOfCards; i++) {
49 | [deck drawRandomCard];
50 | }
51 | }
52 |
53 | #pragma mark - Test Cases
54 |
55 | - (void)testCardsCanBeAdddedAtBothEnds
56 | {
57 | Card *cardBottom = [[BaseDeckTests_CardSubclass alloc] init];
58 | Card *cardTop = [[BaseDeckTests_CardSubclass alloc] init];
59 | Deck *deck = [[Deck alloc] init];
60 | [self createCards:10 inDeck:deck];
61 |
62 | [deck addCard:cardBottom atTop:NO];
63 | [deck addCard:cardTop atTop:YES];
64 | NSUInteger lastCardIndex = [deck.cards count]-1;
65 | XCTAssert(cardBottom == deck.cards[lastCardIndex], @"Bottom card must be the last one");
66 | XCTAssert(cardTop == deck.cards[0], @"Top card must be the first one");
67 | }
68 |
69 | - (void)testDrawCardsFromEmptyDeckDoesntCrash
70 | {
71 | Card *drawCard;
72 | Deck *emptyDeck = [[Deck alloc] init];
73 |
74 | XCTAssertNoThrow(drawCard = [emptyDeck drawRandomCard]);
75 | XCTAssertNil(drawCard);
76 | }
77 |
78 | - (void)testCanDrawFromSingleCardDeck
79 | {
80 | Card *drawCard;
81 | Deck *singleCardDeck = [[Deck alloc] init];
82 | [self createCards:1 inDeck:singleCardDeck];
83 |
84 | XCTAssertNoThrow(drawCard = [singleCardDeck drawRandomCard]);
85 | XCTAssertNotNil(drawCard);
86 | BOOL deckIsEmpty = ![singleCardDeck.cards count];
87 | XCTAssertTrue(deckIsEmpty);
88 | }
89 |
90 | - (void)testCannotDrawMoreCardsThanExistInDeck
91 | {
92 | Card *drawCard;
93 | Deck *manyCardsDeck = [[Deck alloc] init];
94 | [self createCards:2 inDeck:manyCardsDeck];
95 |
96 | XCTAssertNoThrow([self drawAllCardsInDeck:manyCardsDeck]);
97 | XCTAssertNoThrow(drawCard = [manyCardsDeck drawRandomCard]);
98 | XCTAssertNil(drawCard);
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/GcovTestObserver.m:
--------------------------------------------------------------------------------
1 | //
2 | // GcovTestObserver.m
3 | //
4 | // Workaround for XCode 5 bug where __gcov_flush is not called properly when test coverage flags are set.
5 | // http://stackoverflow.com/questions/19136767/generate-gcda-files-with-xcode5-ios7-simulator-and-xctest
6 | //
7 |
8 | #import
9 |
10 | @interface GcovTestObserver : XCTestObserver
11 | @end
12 |
13 | @implementation GcovTestObserver
14 |
15 | - (void) stopObserving
16 | {
17 | [super stopObserving];
18 | UIApplication* application = [UIApplication sharedApplication];
19 | [application.delegate applicationWillTerminate:application];
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/Matchismo Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | pt.mindclick.${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 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/Matchismo Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #import
10 | #endif
11 |
12 | // Custom definitions
13 | #import "Abstract.h"
14 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/PlayingDeckTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingDeckTests.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/10/17.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PlayingDeck.h"
11 | #import "PlayingCard.h"
12 |
13 | #pragma mark - Test Support
14 |
15 | @interface PlayingDeck (Tests)
16 | - (NSMutableArray *)cards;
17 | @end
18 |
19 | #pragma mark - Test Suite
20 |
21 | @interface PlayingDeckTests : XCTestCase
22 |
23 | @end
24 |
25 | @implementation PlayingDeckTests
26 |
27 | - (void)testFullDeckStartsWithAllTheCards
28 | {
29 | PlayingDeck *fullDeck = [[PlayingDeck alloc] init];
30 | NSUInteger cardsInDeck = [fullDeck.cards count];
31 | NSUInteger totalSuits = [[PlayingCard validSuits] count];
32 | NSUInteger totalRanks = [PlayingCard maxRank];
33 | XCTAssertEqual(cardsInDeck, totalSuits * totalRanks);
34 | }
35 |
36 | - (void) testDeckDoesNotContainDuplicateCards
37 | {
38 | PlayingDeck *fullDeck = [[PlayingDeck alloc] init];
39 | NSUInteger cardsInDeck = [fullDeck.cards count];
40 | NSUInteger uniqueCards = [[NSSet setWithArray:fullDeck.cards] count];
41 | XCTAssertEqual(cardsInDeck, uniqueCards);
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/SetDeckTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetDeckTests.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/10/17.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SetDeck.h"
11 | #import "SetCard.h"
12 |
13 | #pragma mark - Test Support
14 |
15 | @interface SetDeck (Tests)
16 | - (NSMutableArray *)cards;
17 | @end
18 |
19 | #pragma mark - Test Suite
20 |
21 | @interface SetDeckTests : XCTestCase
22 |
23 | @end
24 |
25 | @implementation SetDeckTests
26 |
27 | - (void)testFullDeckStartsWithAllTheCards
28 | {
29 | SetDeck *fullDeck = [[SetDeck alloc] init];
30 | NSUInteger cardsInDeck = [fullDeck.cards count];
31 | NSUInteger totalNumbers = 3;
32 | NSUInteger totalSymbols = [[SetCard validSymbols] count];
33 | NSUInteger totalShadings = SET_CARD_SHADING_TYPE_COUNT;
34 | NSUInteger totalColors = SET_CARD_COLOR_TYPE_COUNT;
35 | XCTAssertEqual(cardsInDeck, totalNumbers * totalSymbols * totalShadings * totalColors);
36 | }
37 |
38 | - (void) testDeckDoesNotContainDuplicateCards
39 | {
40 | SetDeck *fullDeck = [[SetDeck alloc] init];
41 | NSUInteger cardsInDeck = [fullDeck.cards count];
42 | NSUInteger uniqueCards = [[NSSet setWithArray:fullDeck.cards] count];
43 | XCTAssertEqual(cardsInDeck, uniqueCards);
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/SetGameTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetGameTests.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/10/23.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SetGame.h"
11 |
12 | @interface SetGameTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation SetGameTests
17 |
18 | // TODO: add tests for the Set game
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Abstract.h:
--------------------------------------------------------------------------------
1 | /**
2 | Since Objective-C does not have real abstract classes, a common idiom is to raise an exception
3 | form the abstract class in case the subclass forgets to override/implement the method.
4 |
5 | Default behaviour in Cocoa (e.g. NSFormatter):
6 |
7 | *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
8 | '*** -stringForObjectValue: only defined for abstract class. Define -[MyFormatter stringForObjectValue:]!'
9 |
10 | References and inspiration:
11 | - https://github.com/stevegeek/cocotron/blob/master/Foundation/NSException/NSRaise.h
12 | - http://xcodeit.net/blog/abstract-classes-and-objective-c.html
13 | - http://stackoverflow.com/questions/1034373/creating-an-abstract-class-in-objective-c
14 | - https://developer.apple.com/library/ios/qa/qa1669/
15 | */
16 |
17 | /*
18 | *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
19 | '-instanceMethod only defined for abstract class. Define -[MySubclass instanceMethod]! (in MDKExceptionsTest.m:76)'
20 | or,
21 | '+classMethod only defined for abstract class. Define +[MySubclass classMethod]! (in MDKExceptionsTest.m:44)'
22 | */
23 | static inline void _MDKInvalidAbstractInvocation(SEL selector, id object, const char *func, const char *file, int line) {
24 | char sign = func[0];
25 | const char *method = sel_getName(selector);
26 | NSString *fileName = [[NSString stringWithUTF8String:file] lastPathComponent];
27 | NSString *message = [NSString stringWithFormat:@"%c%s only defined for abstract class. Define %c[%@ %s]! (in %@:%d)",
28 | sign, method, sign, [object class], method, fileName, line];
29 | @throw [NSException exceptionWithName:NSInvalidArgumentException reason:message userInfo:nil];
30 | }
31 | #define RaiseInvalidAbstractInvocation() _MDKInvalidAbstractInvocation(_cmd, self, __func__, __FILE__, __LINE__)
32 |
33 | /*
34 | *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
35 | '-[MyAbstract init] cannot instantiate abstract class directly. Use a subclass instead! (in MDKExceptionsTest.m:25)'
36 | */
37 | static inline void _MDKInvalidAbstractInstantiationForClass(Class abstract, id object, const char *func, const char *file, int line) {
38 | if ([object class] == abstract) {
39 | NSString *fileName = [[NSString stringWithUTF8String:file] lastPathComponent];
40 | NSString *message = [NSString stringWithFormat:@"%s cannot instantiate abstract class directly. Use a subclass instead! (in %@:%d)",
41 | func, fileName, line];
42 | @throw [NSException exceptionWithName:NSInvalidArgumentException reason:message userInfo:nil];
43 | }
44 | }
45 | #define RaiseInvalidAbstractInstantiationForClass(CLASS) _MDKInvalidAbstractInstantiationForClass(CLASS, self, __func__, __FILE__, __LINE__)
46 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/CardGameAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // CardGameAppDelegate.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/22.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CardGameAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/CardGameAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // CardGameAppDelegate.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/22.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "CardGameAppDelegate.h"
10 |
11 | @implementation CardGameAppDelegate
12 |
13 | // http://stackoverflow.com/questions/19136767/generate-gcda-files-with-xcode5-ios7-simulator-and-xctest
14 | #ifdef DEBUG
15 | + (void)initialize {
16 | [[NSUserDefaults standardUserDefaults] setValue:@"XCTestLog,GcovTestObserver"
17 | forKey:@"XCTestObserverClass"];
18 | }
19 | #endif
20 |
21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
22 | {
23 | // Override point for customization after application launch.
24 | return YES;
25 | }
26 |
27 | - (void)applicationWillResignActive:(UIApplication *)application
28 | {
29 | // 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.
30 | // 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.
31 | }
32 |
33 | - (void)applicationDidEnterBackground:(UIApplication *)application
34 | {
35 | // 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.
36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
37 | }
38 |
39 | - (void)applicationWillEnterForeground:(UIApplication *)application
40 | {
41 | // 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.
42 | }
43 |
44 | - (void)applicationDidBecomeActive:(UIApplication *)application
45 | {
46 | // 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.
47 | }
48 |
49 | - (void)applicationWillTerminate:(UIApplication *)application
50 | {
51 | #ifdef DEBUG
52 | extern void __gcov_flush(void);
53 | __gcov_flush();
54 | #endif
55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/Card.h:
--------------------------------------------------------------------------------
1 | //
2 | // Card.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /** Abstract class. */
12 | @interface Card : NSObject
13 |
14 | ///--------------------------------------------------------------------------------
15 | /// @name Methods to Implement in a Subclass
16 | ///--------------------------------------------------------------------------------
17 |
18 | - (int)match:(NSArray *)otherCards;
19 |
20 | ///--------------------------------------------------------------------------------
21 | /// @name Card Information
22 | ///--------------------------------------------------------------------------------
23 |
24 | @property (strong, nonatomic) NSString *contents;
25 | @property (nonatomic, getter = isFaceUp) BOOL faceup;
26 | @property (nonatomic, getter = isUnplayable) BOOL unplayable;
27 | - (NSString *)description;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/Card.m:
--------------------------------------------------------------------------------
1 | //
2 | // Card.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "Card.h"
10 |
11 | @implementation Card
12 |
13 | #pragma mark - Abstract
14 |
15 | - (int)match:(NSArray *)otherCards
16 | {
17 | RaiseInvalidAbstractInvocation();
18 | return 0;
19 | }
20 |
21 | #pragma mark - Initialization
22 |
23 | - (id)init
24 | {
25 | RaiseInvalidAbstractInstantiationForClass([Card class]);
26 | self = [super init];
27 | return self;
28 | }
29 |
30 | #pragma mark - Methods
31 |
32 | - (NSString *)description
33 | {
34 | return self.contents;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/Deck.h:
--------------------------------------------------------------------------------
1 | //
2 | // Deck.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Card.h"
11 |
12 | @interface Deck : NSObject
13 |
14 | - (void)addCard:(Card *)card atTop:(BOOL)yn;
15 | - (Card *)drawRandomCard;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/Deck.m:
--------------------------------------------------------------------------------
1 | //
2 | // Deck.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "Deck.h"
10 |
11 | @interface Deck()
12 | @property (strong, nonatomic) NSMutableArray *cards; // of Card
13 | @end
14 |
15 | @implementation Deck
16 |
17 | - (NSMutableArray *)cards
18 | {
19 | if (!_cards) _cards = [[NSMutableArray alloc] init];
20 | return _cards;
21 | }
22 |
23 | - (void)addCard:(Card *)card atTop:(BOOL)atTop
24 | {
25 | if (atTop) {
26 | [self.cards insertObject:card atIndex:0];
27 | } else {
28 | [self.cards addObject:card];
29 | }
30 | }
31 |
32 | - (Card *)drawRandomCard
33 | {
34 | Card *randomCard;
35 |
36 | if ([self.cards count]) {
37 | unsigned index = arc4random() % [self.cards count];
38 | randomCard = self.cards[index];
39 | [self.cards removeObjectAtIndex:index];
40 | }
41 |
42 | return randomCard;
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayResult.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSUInteger, PlayStatus) {
12 | PlayStatusCardFlipped,
13 | PlayStatusCardsMatch,
14 | PlayStatusCardsMismatch,
15 | };
16 |
17 | @interface PlayResult : NSObject
18 |
19 | ///--------------------------------------------------------------------------------
20 | /// @name Initializing a Result
21 | ///--------------------------------------------------------------------------------
22 |
23 | /** Designated initializer. */
24 | - (id)initWithCards:(NSArray *)cards outcome:(PlayStatus)result score:(int)point;
25 |
26 |
27 | ///--------------------------------------------------------------------------------
28 | /// @name Retrieving Result Information
29 | ///--------------------------------------------------------------------------------
30 |
31 | @property (nonatomic, strong, readonly) NSArray *cards; // of Card
32 | @property (nonatomic, readonly) PlayStatus outcome;
33 | @property (nonatomic, readonly) NSInteger score;
34 |
35 | - (NSString *)description;
36 |
37 | - (NSString *)outcomeString;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayResult.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "PlayResult.h"
10 |
11 | @implementation PlayResult
12 |
13 | #pragma mark - Initializers
14 |
15 | - (id)initWithCards:(NSArray *)cards outcome:(PlayStatus)result score:(int)points
16 | {
17 | self = [super init];
18 | if (self) {
19 | _cards = cards;
20 | _outcome = result;
21 | _score = points;
22 | }
23 | return self;
24 | }
25 |
26 | - (id)init
27 | {
28 | return [self initWithCards:nil outcome:0 score:0];
29 | }
30 |
31 | #pragma mark - Methods
32 |
33 | - (NSString *)outcomeString
34 | {
35 | NSString *translation = @"";
36 | switch (self.outcome) {
37 | case PlayStatusCardFlipped: translation = @"Flipped"; break;
38 | case PlayStatusCardsMatch: translation = @"Matched"; break;
39 | case PlayStatusCardsMismatch: translation = @"Didn't match"; break;
40 | }
41 | return translation;
42 | }
43 |
44 | #pragma mark - NSObject
45 |
46 | - (NSString *)description
47 | {
48 | NSString *cardNames = [self.cards componentsJoinedByString:@" "];
49 | return [NSString stringWithFormat:@"%@ %@ (%+d)", [self outcomeString], cardNames, self.score];
50 | }
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayingCard.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingCard.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Card.h"
11 |
12 | extern NSString * const PlayingCardSymbolHearts;
13 | extern NSString * const PlayingCardSymbolDiamonds;
14 | extern NSString * const PlayingCardSymbolSpades;
15 | extern NSString * const PlayingCardSymbolClubs;
16 |
17 | @interface PlayingCard : Card
18 |
19 | @property (strong, nonatomic) NSString *suit;
20 | @property (nonatomic) NSUInteger rank;
21 |
22 | + (NSArray *)validSuits;
23 | + (NSUInteger)maxRank;
24 |
25 | @end
26 |
27 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayingCard.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingCard.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "PlayingCard.h"
10 |
11 | NSString * const PlayingCardSymbolHearts = @"♥";
12 | NSString * const PlayingCardSymbolDiamonds = @"♦";
13 | NSString * const PlayingCardSymbolSpades = @"♠";
14 | NSString * const PlayingCardSymbolClubs = @"♣";
15 |
16 | @implementation PlayingCard
17 |
18 | #pragma mark - Class
19 |
20 | + (NSArray *)validSuits
21 | {
22 | static NSArray *suits = nil;
23 | if (!suits) suits = @[PlayingCardSymbolHearts,
24 | PlayingCardSymbolDiamonds,
25 | PlayingCardSymbolSpades,
26 | PlayingCardSymbolClubs];
27 | return suits;
28 | }
29 |
30 | + (NSArray *)validRanks
31 | {
32 | static NSArray *ranks = nil;
33 | if (!ranks) ranks = @[@"?", @"A", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"J", @"Q", @"K"];
34 | return ranks;
35 | }
36 |
37 | + (NSUInteger)maxRank
38 | {
39 | return [[self validRanks] count] - 1;
40 | }
41 |
42 | #pragma mark - Properties
43 |
44 | @synthesize suit = _suit;
45 |
46 | - (NSString *)suit
47 | {
48 | return (_suit)? _suit : @"Ø";
49 | }
50 |
51 | - (void)setSuit:(NSString *)suit
52 | {
53 | if ([[PlayingCard validSuits] containsObject:suit]) {
54 | _suit = suit;
55 | }
56 | }
57 |
58 | - (void)setRank:(NSUInteger)rank {
59 | if (rank <= [PlayingCard maxRank]) {
60 | _rank = rank;
61 | }
62 | }
63 |
64 | #pragma mark - Methods
65 |
66 | - (NSString *)contents
67 | {
68 | NSArray *ranks = [PlayingCard validRanks];
69 | return [ranks[self.rank] stringByAppendingString:self.suit];
70 | }
71 |
72 | - (int)match:(NSArray *)otherCards
73 | {
74 | int score = 0;
75 | BOOL(^isSameSuit)(id, NSUInteger, BOOL*);
76 | BOOL(^isSameRank)(id, NSUInteger, BOOL*);
77 |
78 | if ([otherCards count] > 0) {
79 | // Define the matching block conditions
80 | isSameSuit = ^(id obj, NSUInteger idx, BOOL *stop) {
81 | return (BOOL)([obj isKindOfClass:[PlayingCard class]]? [self.suit isEqualToString:[obj suit]] : NO);
82 | };
83 | isSameRank = ^(id obj, NSUInteger idx, BOOL *stop) {
84 | return (BOOL)([obj isKindOfClass:[PlayingCard class]]? self.rank == [obj rank] : NO);
85 | };
86 |
87 | // Does suit or rank match in all cards?
88 | BOOL suitsMatch = ([otherCards count] == [[otherCards indexesOfObjectsPassingTest:isSameSuit] count]);
89 | BOOL ranksMatch = ([otherCards count] == [[otherCards indexesOfObjectsPassingTest:isSameRank] count]);
90 |
91 | // Give out points
92 | if (suitsMatch) {
93 | score = 1;
94 | } else if (ranksMatch) {
95 | score = 4;
96 | }
97 | }
98 | return score;
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayingDeck.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingDeck.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Deck.h"
11 |
12 | @interface PlayingDeck : Deck
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayingDeck.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingDeck.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "PlayingDeck.h"
10 | #import "PlayingCard.h"
11 |
12 | @implementation PlayingDeck
13 |
14 | - (id)init
15 | {
16 | self = [super init];
17 | if (self) {
18 | for (NSString *suit in [PlayingCard validSuits]) {
19 | for (NSUInteger rank = 1; rank <= [PlayingCard maxRank]; rank++) {
20 | PlayingCard *card = [[PlayingCard alloc] init];
21 | card.suit = suit;
22 | card.rank = rank;
23 | [self addCard:card atTop:YES];
24 | }
25 | }
26 | }
27 | return self;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/PlayingGame.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingGame.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/08/02.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Deck.h"
11 | #import "Card.h"
12 | @class PlayResult;
13 |
14 | typedef struct {
15 | NSInteger flipCost;
16 | NSInteger mismatchPenalty;
17 | NSInteger matchBonus;
18 | } ScoringDefinitions;
19 |
20 | @interface PlayingGame : NSObject
21 |
22 | /** Designated Initializer */
23 | - (id)initWithCardCount:(NSUInteger)count
24 | fromDeck:(Deck *)deck
25 | matchCount:(NSUInteger)numCards
26 | bonusPenalties:(ScoringDefinitions)weights;
27 |
28 | - (id)initWithCardCount:(NSUInteger)count
29 | fromDeck:(Deck *)deck;
30 |
31 | @property (readonly, nonatomic) int score;
32 | @property (nonatomic) NSUInteger numCardsToMatch;
33 |
34 | - (PlayResult *)lastPlay;
35 |
36 | - (NSArray *)lastPlays;
37 |
38 | - (void)flipCardAtIndex:(NSUInteger)index;
39 |
40 | - (Card *)cardAtIndex:(NSUInteger)index;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetCard.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetCard.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Card.h"
11 |
12 | extern NSString * const SetCardSymbolDiamond;
13 | extern NSString * const SetCardSymbolSquiggle;
14 | extern NSString * const SetCardSymbolOval;
15 |
16 | typedef NS_ENUM(NSInteger, SetCardShadingType) {
17 | SetCardShadingSolid,
18 | SetCardShadingStriped,
19 | SetCardShadingOpen,
20 | SET_CARD_SHADING_TYPE_COUNT
21 | };
22 |
23 | typedef NS_ENUM(NSInteger, SetCardColorType) {
24 | SetCardColorRed,
25 | SetCardColorGreen,
26 | SetCardColorPurple,
27 | SET_CARD_COLOR_TYPE_COUNT
28 | };
29 |
30 | /**
31 | The Set cards vary in four features: number, symbol, shading, and color.
32 |
33 | A set consists of three cards which satisfy all of these conditions:
34 |
35 | - They all have the same number, or they have three different numbers.
36 | - They all have the same symbol, or they have three different symbols.
37 | - They all have the same shading, or they have three different shadings.
38 | - They all have the same color, or they have three different colors.
39 |
40 | The rules of Set are summarized by: If you can sort a group of three cards
41 | into "Two of ____ and one of _____," then it is not a set.
42 |
43 | For example, these three cards form a set:
44 |
45 | - One red striped diamond
46 | - Two red solid diamonds
47 | - Three red open diamonds
48 |
49 | Given any two cards from the deck, there will be one and only one other
50 | card that forms a set with them.
51 | */
52 | @interface SetCard : Card
53 |
54 | /** Designated initializer. */
55 | - (id)initWithNumber:(NSUInteger)number
56 | shading:(SetCardShadingType)shading
57 | color:(SetCardColorType)color
58 | symbol:(NSString *)symbol;
59 |
60 | /** number = one, two, or three. */
61 | @property (readonly, nonatomic) NSUInteger number;
62 |
63 | /** symbol = diamond, squiggle, oval. */
64 | @property (readonly, strong, nonatomic) NSString *symbol;
65 |
66 | /** shading = solid, striped, or open. */
67 | @property (readonly, nonatomic) SetCardShadingType shading;
68 |
69 | /** color = red, green, or purple. */
70 | @property (readonly, nonatomic) SetCardColorType color;
71 |
72 | /** List of NSString symbols allowed for the Set cards. */
73 | + (NSArray *)validSymbols;
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetCard.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetCard.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "SetCard.h"
10 |
11 | NSString * const SetCardSymbolDiamond = @"▲";
12 | NSString * const SetCardSymbolSquiggle = @"■";
13 | NSString * const SetCardSymbolOval = @"●";
14 |
15 | @implementation SetCard
16 |
17 | #pragma mark - Class
18 |
19 | /** Validates if a property of the cards is all the same or all distinct. */
20 | + (BOOL)allSameOrDifferent:(SEL)property forArray:(NSArray *)cards
21 | {
22 | return ([self allElementsInArray:cards haveTheSame:property])
23 | || ([self allElementsInArray:cards haveDistinct:property]);
24 | }
25 |
26 | + (BOOL)allElementsInArray:(NSArray *)cards haveTheSame:(SEL)property
27 | {
28 | return (1 == [self countUniquePropertyValuesFor:property inCards:cards]);
29 | }
30 |
31 | + (BOOL)allElementsInArray:(NSArray *)cards haveDistinct:(SEL)property
32 | {
33 | return ([cards count] == [self countUniquePropertyValuesFor:property inCards:cards]);
34 | }
35 |
36 | /**
37 | Since sets only contain unique values, making a set out of the values of the property
38 | is an easy way to count the number of unique values for that property.
39 | */
40 | + (NSUInteger)countUniquePropertyValuesFor:(SEL)property inCards:(NSArray *)cards
41 | {
42 | NSString *propertyName = NSStringFromSelector(property);
43 | NSArray *propertyValues = [cards valueForKey:propertyName];
44 | NSSet *uniquePropertyValues = [NSSet setWithArray:propertyValues];
45 | return [uniquePropertyValues count];
46 | }
47 |
48 | + (NSArray *)validSymbols
49 | {
50 | static NSArray *symbols = nil;
51 | if (!symbols) symbols = @[SetCardSymbolDiamond, SetCardSymbolOval, SetCardSymbolSquiggle];
52 | return symbols;
53 | }
54 |
55 | #pragma mark - Initialization
56 |
57 | - (id)initWithNumber:(NSUInteger)number
58 | shading:(SetCardShadingType)shading
59 | color:(SetCardColorType)color
60 | symbol:(NSString *)symbol
61 | {
62 | self = [super init];
63 | if (self) {
64 | // validate params
65 | if (!(number >= 1 && number <= 3)
66 | || !(shading >= 0 && shading < SET_CARD_SHADING_TYPE_COUNT)
67 | || !(color >= 0 && color < SET_CARD_COLOR_TYPE_COUNT)
68 | || ![[SetCard validSymbols] containsObject:symbol])
69 | {
70 | return nil;
71 | }
72 |
73 | // define the card
74 | _number = number;
75 | _symbol = symbol;
76 | _shading = shading;
77 | _color = color;
78 | }
79 | return self;
80 | }
81 |
82 | - (id)init
83 | {
84 | // "reasonable" settings for a default card
85 | return [self initWithNumber:1
86 | shading:SetCardShadingSolid
87 | color:SetCardColorRed
88 | symbol:[SetCard validSymbols][0]];
89 | }
90 |
91 | #pragma mark - Methods
92 |
93 | - (NSString *)contents
94 | {
95 | return [@"" stringByPaddingToLength:self.number withString:self.symbol startingAtIndex:0];
96 | }
97 |
98 | - (int)match:(NSArray *)otherCards
99 | {
100 | int score = 0;
101 |
102 | // Are all other cards a SetCard?
103 | BOOL(^isSameClass)(id, NSUInteger, BOOL*) = ^(id obj, NSUInteger idx, BOOL *stop) {
104 | return [obj isKindOfClass:[SetCard class]];
105 | };
106 | BOOL isOnlySetCards = ([otherCards count] == [[otherCards indexesOfObjectsPassingTest:isSameClass] count]);
107 |
108 | // Compare with several SetCards...
109 | if ([otherCards count] > 0 && isOnlySetCards) {
110 | NSArray *allCards = [otherCards arrayByAddingObject:self];
111 |
112 | // Penalise if some characteristic didn't match
113 | if (![SetCard allSameOrDifferent:@selector(number) forArray:allCards]) score--;
114 | if (![SetCard allSameOrDifferent:@selector(shading) forArray:allCards]) score--;
115 | if (![SetCard allSameOrDifferent:@selector(color) forArray:allCards]) score--;
116 | if (![SetCard allSameOrDifferent:@selector(symbol) forArray:allCards]) score--;
117 |
118 | // Give points for matching a set
119 | if (!(score < 0)) score = 3;
120 | }
121 | return score;
122 | }
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetDeck.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetDeck.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Deck.h"
11 |
12 | /**
13 | The Set deck consists of 81 cards.
14 | */
15 | @interface SetDeck : Deck
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetDeck.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetDeck.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "SetDeck.h"
10 | #import "SetCard.h"
11 |
12 | @implementation SetDeck
13 |
14 | - (id)init
15 | {
16 | self = [super init];
17 | if (self) {
18 | for (NSUInteger number = 1; number <= 3; number++) {
19 | for (NSString *symbol in [SetCard validSymbols]) {
20 | for (SetCardShadingType shade = 0; shade < SET_CARD_SHADING_TYPE_COUNT; shade++) {
21 | for (SetCardColorType color = 0; color < SET_CARD_COLOR_TYPE_COUNT; color++) {
22 | SetCard *card = [[SetCard alloc] initWithNumber:number
23 | shading:shade
24 | color:color
25 | symbol:symbol];
26 | if (card) [self addCard:card atTop:YES];
27 | }
28 | }
29 | }
30 |
31 | }
32 | }
33 | return self;
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetGame.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetGame.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "PlayingGame.h"
10 | #import "SetDeck.h"
11 | #import "SetCard.h"
12 |
13 | @interface SetGame : PlayingGame
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Components/SetGame.m:
--------------------------------------------------------------------------------
1 | //
2 | // SetGame.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "SetGame.h"
10 |
11 | @implementation SetGame
12 |
13 | #pragma mark - NSObject
14 |
15 | - (NSString *)description
16 | {
17 | return @"Sets";
18 | }
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/CardGameViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CardGameViewController.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/22.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | @class PlayingGame;
11 |
12 | @interface CardGameViewController : UIViewController
13 | {
14 | @protected
15 | PlayingGame *_game;
16 | }
17 | @end
18 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/CardGameViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CardGameViewController.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/22.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "CardGameViewController.h"
10 | #import "PlayingGame.h"
11 | #import "PlayingDeck.h"
12 | #import "GameResult.h"
13 | #import "PlayResult.h"
14 |
15 | @interface CardGameViewController ()
16 |
17 | @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
18 | @property (weak, nonatomic) IBOutlet UILabel *flipsDisplay;
19 | @property (weak, nonatomic) IBOutlet UILabel *scoreDisplay;
20 | @property (weak, nonatomic) IBOutlet UILabel *messageDisplay;
21 | @property (weak, nonatomic) IBOutlet UISegmentedControl *gameModeSelector;
22 | @property (weak, nonatomic) IBOutlet UISlider *messageHistory;
23 | @property (nonatomic) int flipsCount;
24 | @property (strong, nonatomic) PlayingGame *game;
25 | @property (strong, nonatomic) GameResult *gameResult;
26 |
27 | @end
28 |
29 | @implementation CardGameViewController
30 |
31 | - (GameResult *)gameResult
32 | {
33 | if (!_gameResult) {
34 | _gameResult = [[GameResult alloc] init];
35 | _gameResult.gameName = self.game.description;
36 | }
37 | return _gameResult;
38 | }
39 |
40 | - (PlayingGame *)game
41 | {
42 | if (!_game) _game = [[PlayingGame alloc] initWithCardCount:[self.cardButtons count]
43 | fromDeck:[[PlayingDeck alloc] init]
44 | matchCount:(self.gameModeSelector.selectedSegmentIndex)? 3 : 2
45 | bonusPenalties:(ScoringDefinitions){-1, -2, 4}];
46 | return _game;
47 | }
48 |
49 | - (void)setCardButtons:(NSArray *)cardButtons
50 | {
51 | _cardButtons = cardButtons;
52 | [self updateUI];
53 | }
54 |
55 | - (void)updateUI
56 | {
57 | for (UIButton *cardButton in self.cardButtons) {
58 | Card *card = [self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
59 | // Card face
60 | [cardButton setTitle:card.contents forState:UIControlStateSelected];
61 | [cardButton setTitle:card.contents forState:UIControlStateSelected|UIControlStateDisabled];
62 | // Card back
63 | cardButton.imageEdgeInsets = UIEdgeInsetsMake(4.0, 4.0, 4.0, 4.0);
64 | UIImage *cardBackImage = [UIImage imageNamed:@"cardback"];
65 | [cardButton setImage:(card.isFaceUp)? nil : cardBackImage forState:UIControlStateNormal];
66 | // Card state
67 | cardButton.selected = card.isFaceUp;
68 | cardButton.enabled = !card.isUnplayable;
69 | cardButton.alpha = (card.isUnplayable)? 0.3 : 1.0;
70 | }
71 | self.scoreDisplay.text = [NSString stringWithFormat:@"Score: %d", self.game.score];
72 | self.messageDisplay.text = [[self.game lastPlay] description];
73 | }
74 |
75 | - (void)setFlipsCount:(int)count
76 | {
77 | _flipsCount = count;
78 | self.flipsDisplay.text = [NSString stringWithFormat:@"Flips: %d", self.flipsCount];
79 | }
80 |
81 | - (IBAction)flipCard:(UIButton *)sender
82 | {
83 | self.gameModeSelector.enabled = NO;
84 | [self.game flipCardAtIndex:[self.cardButtons indexOfObject:sender]];
85 | if (sender.isEnabled && !sender.isSelected) {
86 | self.flipsCount++; // Card flipped up
87 | }
88 | self.messageHistory.maximumValue = [[self.game lastPlays] count];
89 | self.messageHistory.value = [[self.game lastPlays] count];
90 | self.messageDisplay.alpha = 1.0;
91 | [self updateUI];
92 | self.gameResult.score = self.game.score;
93 | }
94 |
95 | - (IBAction)dealGame {
96 | self.gameModeSelector.enabled = YES;
97 | self.game = nil;
98 | self.flipsCount = 0;
99 | self.messageHistory.maximumValue = self.flipsCount;
100 | [self updateUI];
101 | self.gameResult = nil;
102 | }
103 |
104 | - (IBAction)changeGameMode:(UISegmentedControl *)sender
105 | {
106 | self.game.numCardsToMatch = (sender.selectedSegmentIndex)? 3 : 2;
107 | }
108 |
109 | - (IBAction)timeTravel:(UISlider *)sender {
110 | if (sender.maximumValue > 0) {
111 | int index = (int)[sender value];
112 | self.messageDisplay.text = (!index)? @"" : [[self.game lastPlays][index - 1] description];
113 | self.messageDisplay.alpha = (index == sender.maximumValue)? 1.0 : 0.3;
114 | }
115 | }
116 |
117 | @end
118 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/GameResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameResult.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/10.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GameResult : NSObject
12 |
13 | + (NSArray *)allGameResults; // of GameResult
14 |
15 | @property (readonly, nonatomic) NSDate *start;
16 | @property (readonly, nonatomic) NSDate *end;
17 | @property (readonly, nonatomic) NSTimeInterval duration;
18 | @property (nonatomic) int score;
19 | @property (nonatomic) NSString *gameName;
20 |
21 | - (NSComparisonResult)compareDateDescending:(GameResult *)otherResult;
22 | - (NSComparisonResult)compareDurationAscending:(GameResult *)otherResult;
23 | - (NSComparisonResult)compareScoreDescending:(GameResult *)otherResult;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/GameResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // GameResult.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/10.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "GameResult.h"
10 |
11 | @interface GameResult()
12 |
13 | @property (readwrite, nonatomic) NSDate *start;
14 | @property (readwrite, nonatomic) NSDate *end;
15 |
16 | @end
17 |
18 | @implementation GameResult
19 |
20 | #define KEY_ALL_RESULTS @"GameResult.AllResults"
21 | #define KEY_START @"StartDate"
22 | #define KEY_END @"EndDate"
23 | #define KEY_SCORE @"Score"
24 | #define KEY_GAME @"GameName"
25 |
26 | #pragma mark - Class
27 |
28 | + (NSArray *)allGameResults
29 | {
30 | NSMutableArray *allGameResults = [[NSMutableArray alloc] init];
31 |
32 | for (id plist in [[[NSUserDefaults standardUserDefaults] dictionaryForKey:KEY_ALL_RESULTS] allValues]) {
33 | GameResult *result = [[GameResult alloc] initFromPropertyList:plist];
34 | [allGameResults addObject:result];
35 | }
36 |
37 | return allGameResults;
38 | }
39 |
40 | #pragma mark - Initializers
41 |
42 | /** Designated initializer */
43 | - (id)init
44 | {
45 | self = [super init];
46 | if (self) {
47 | _start = [NSDate date];
48 | _end = _start;
49 | }
50 | return self;
51 | }
52 |
53 | - (id)initFromPropertyList:(id)plist
54 | {
55 | self = [self init];
56 | if (self) {
57 | if ([plist isKindOfClass:[NSDictionary class]]) {
58 | _start = plist[KEY_START];
59 | _end = plist[KEY_END];
60 | _score = [plist[KEY_SCORE] intValue];
61 | _gameName = plist[KEY_GAME];
62 | if (!_start || !_end) self = nil;
63 | }
64 | }
65 | return self;
66 | }
67 |
68 | #pragma mark - Properties
69 |
70 | - (NSTimeInterval)duration
71 | {
72 | return [self.end timeIntervalSinceDate:self.start];
73 | }
74 |
75 | - (void)setScore:(int)score
76 | {
77 | _score = score;
78 | self.end = [NSDate date];
79 | [self synchronize];
80 | }
81 |
82 | #pragma mark - Methods
83 |
84 | - (NSDictionary *)asPropertyList
85 | {
86 | return @{KEY_START: self.start,
87 | KEY_END: self.end,
88 | KEY_SCORE: @(self.score),
89 | KEY_GAME: self.gameName};
90 | }
91 |
92 | - (NSComparisonResult)compareDateDescending:(GameResult *)otherResult
93 | {
94 | return [otherResult.start compare:self.end];
95 | }
96 |
97 | - (NSComparisonResult)compareDurationAscending:(GameResult *)otherResult
98 | {
99 | return [@(self.duration) compare:@(otherResult.duration)];
100 | }
101 |
102 | - (NSComparisonResult)compareScoreDescending:(GameResult *)otherResult
103 | {
104 | return [@(otherResult.score) compare:@(self.score)];
105 | }
106 |
107 | - (void)synchronize
108 | {
109 | // Fetch
110 | NSMutableDictionary *allGameResults = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:KEY_ALL_RESULTS ] mutableCopy];
111 | if (!allGameResults) allGameResults = [[NSMutableDictionary alloc] init];
112 | // Change
113 | allGameResults[[self.start description]] = [self asPropertyList];
114 | // Store
115 | [[NSUserDefaults standardUserDefaults] setObject:allGameResults forKey:KEY_ALL_RESULTS];
116 | [[NSUserDefaults standardUserDefaults] synchronize];
117 | }
118 |
119 | #pragma mark - NSObject
120 |
121 | - (NSString *)description
122 | {
123 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
124 | [formatter setDateStyle:NSDateFormatterMediumStyle];
125 | [formatter setTimeStyle:NSDateFormatterShortStyle];
126 | return [NSString stringWithFormat:@"%@:\t%d\t@ %@ (%0g)", self.gameName, self.score, [formatter stringFromDate:self.end], round(self.duration)];
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/GameResultViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // GameResultViewController.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/10.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface GameResultViewController : UIViewController
12 |
13 | @property (weak, nonatomic) IBOutlet UITextView *display;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/GameResultViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // GameResultViewController.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/10.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "GameResultViewController.h"
10 | #import "GameResult.h"
11 |
12 | @interface GameResultViewController()
13 | @property (nonatomic) SEL criteriaForSorting;
14 | @end
15 |
16 | @implementation GameResultViewController
17 |
18 | #pragma mark - Boilerplate template (for reference)
19 |
20 | - (void)setup
21 | {
22 | // things that can't wait until viewDidLoad
23 | }
24 |
25 | - (void)awakeFromNib
26 | {
27 | [self setup];
28 | }
29 |
30 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
31 | {
32 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
33 | [self setup];
34 | return self;
35 | }
36 |
37 | #pragma mark - Properties
38 |
39 | @synthesize criteriaForSorting = _criteriaForSorting;
40 |
41 | - (SEL)criteriaForSorting
42 | {
43 | if (!_criteriaForSorting) _criteriaForSorting = @selector(compareDateDescending:);
44 | return _criteriaForSorting;
45 | }
46 |
47 | - (void)setCriteriaForSorting:(SEL)criteriaForSorting
48 | {
49 | _criteriaForSorting = criteriaForSorting;
50 | [self updateUI];
51 | }
52 |
53 | #pragma mark - Methods
54 |
55 | - (void)updateUI
56 | {
57 | self.display.text = [[[GameResult allGameResults] sortedArrayUsingSelector:self.criteriaForSorting] componentsJoinedByString:@"\n"];
58 | }
59 |
60 | - (IBAction)defineSortingCriteria:(UIButton *)sender
61 | {
62 | int tag = sender.tag;
63 | switch (tag) {
64 | case 2:
65 | self.criteriaForSorting = @selector(compareScoreDescending:);
66 | break;
67 | case 3:
68 | self.criteriaForSorting = @selector(compareDurationAscending:);
69 | break;
70 | default:
71 | self.criteriaForSorting = @selector(compareDateDescending:);
72 | }
73 | }
74 |
75 | #pragma mark - UIViewController
76 |
77 | - (void)viewWillAppear:(BOOL)animated
78 | {
79 | [super viewWillAppear:animated];
80 | [self updateUI];
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Controllers/SetGameViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SetGameViewController.h
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/09/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CardGameViewController.h"
11 |
12 | @interface SetGameViewController : CardGameViewController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Settings.xcconfig
3 | //
4 | // Created by Hugo Ferreira on 2013/10/10.
5 | // Copyright (c) 2013 Mindclick. All rights reserved.
6 | //
7 |
8 | #include "Warnings.xcconfig"
9 |
10 | // Override some of the warnings settings
11 | GCC_TREAT_WARNINGS_AS_ERRORS = NO
12 |
13 | // Setup code coverage analysis
14 | // http://blog.nwoolls.com/2013/02/08/visualizing-code-coverage-with-xcode/
15 | GCC_GENERATE_TEST_COVERAGE_FILES = YES
16 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES
17 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Matchismo-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIcons
12 |
13 | CFBundleIcons~ipad
14 |
15 | CFBundleIdentifier
16 | pt.mindclick.cs193p.${PRODUCT_NAME:rfc1034identifier}
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundleName
20 | ${PRODUCT_NAME}
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | 1.0
25 | CFBundleSignature
26 | ????
27 | CFBundleVersion
28 | 1.0
29 | LSRequiresIPhoneOS
30 |
31 | UIMainStoryboardFile
32 | MainStoryboard
33 | UIRequiredDeviceCapabilities
34 |
35 | armv7
36 |
37 | UISupportedInterfaceOrientations
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationLandscapeLeft
41 | UIInterfaceOrientationLandscapeRight
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Matchismo-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Matchismo' target in the 'Matchismo' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
16 | // Custom definitions
17 | #import "Abstract.h"
18 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "1x",
6 | "size" : "57x57"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "2x",
11 | "size" : "57x57"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "60x60"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "1x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "29x29"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "2x",
31 | "size" : "40x40"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "filename" : "Default@2x.png",
9 | "scale" : "2x"
10 | },
11 | {
12 | "extent" : "full-screen",
13 | "idiom" : "iphone",
14 | "subtype" : "retina4",
15 | "filename" : "Default-568h@2x.png",
16 | "minimum-system-version" : "7.0",
17 | "orientation" : "portrait",
18 | "scale" : "2x"
19 | },
20 | {
21 | "orientation" : "portrait",
22 | "idiom" : "iphone",
23 | "extent" : "full-screen",
24 | "filename" : "Default.png",
25 | "scale" : "1x"
26 | },
27 | {
28 | "orientation" : "portrait",
29 | "idiom" : "iphone",
30 | "extent" : "full-screen",
31 | "filename" : "Default@2x-1.png",
32 | "scale" : "2x"
33 | },
34 | {
35 | "orientation" : "portrait",
36 | "idiom" : "iphone",
37 | "extent" : "full-screen",
38 | "filename" : "Default-568h@2x-1.png",
39 | "subtype" : "retina4",
40 | "scale" : "2x"
41 | }
42 | ],
43 | "info" : {
44 | "version" : 1,
45 | "author" : "xcode"
46 | }
47 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default-568h@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default-568h@2x-1.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default@2x-1.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/LaunchImage.launchimage/Default@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/hash.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "hash.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/hash.imageset/hash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/hash.imageset/hash.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/set.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "set.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/set.imageset/set.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/set.imageset/set.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/spade.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "spade.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/spade.imageset/spade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/Tab Bar/spade.imageset/spade.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/cardback.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "cardback.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "cardback@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/cardback.imageset/cardback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/cardback.imageset/cardback.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/cardback.imageset/cardback@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Matchismo/Resources/Images.xcassets/cardback.imageset/cardback@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Warnings.xcconfig
3 | //
4 | // Created by Steven Fisher:
5 | // http://tewha.net/2010/11/xcode-warnings/
6 | // See also:
7 | // http://boredzo.org/blog/archives/2009-11-07/warnings
8 | //
9 |
10 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES
11 | GCC_WARN_SHADOW = YES
12 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES
13 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
14 | GCC_WARN_ABOUT_RETURN_TYPE = YES
15 | GCC_WARN_MISSING_PARENTHESES = YES
16 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES
17 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES
18 | GCC_WARN_SIGN_COMPARE = YES
19 | GCC_WARN_UNDECLARED_SELECTOR = YES
20 | GCC_WARN_UNUSED_FUNCTION = YES
21 | GCC_WARN_UNUSED_LABEL = YES
22 | GCC_WARN_UNUSED_VALUE = YES
23 | GCC_WARN_UNUSED_VARIABLE = YES
24 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
25 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES
26 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES
27 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES
28 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES
29 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES
30 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
31 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES
32 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES
33 | OTHER_CFLAGS = -Wextra -Wno-unused-parameter
34 | GCC_TREAT_WARNINGS_AS_ERRORS = YES
35 | RUN_CLANG_STATIC_ANALYZER = YES
36 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Matchismo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Matchismo
4 | //
5 | // Created by Hugo Ferreira on 2013/07/22.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "CardGameAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CardGameAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Screen Shot 2013-08-27 at 18.49.06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Screen Shot 2013-08-27 at 18.49.06.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/Screen Shot 2013-09-25 at 14.11.19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Matchismo/Screen Shot 2013-09-25 at 14.11.19.png
--------------------------------------------------------------------------------
/2013 Winter/Matchismo/TODO.h:
--------------------------------------------------------------------------------
1 |
2 | /* TODO: Maybe test fixture should be is a separate classs?
3 | (so test code is for sure uncapable to change the ivar) */
4 |
5 | /* IGNORE: Skip the rest of assignment 3. Not much learning value left in there! */
6 |
7 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/README.md:
--------------------------------------------------------------------------------
1 | [The Clean Architecture | 8th Light](http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html)
2 |
3 | 
4 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/ImageDetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageDetailViewController.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ImageEntity.h"
11 |
12 | @interface ImageDetailViewController : UIViewController
13 |
14 | @property (strong, nonatomic) ImageEntity *imageToDisplay;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/ImageDetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageDetailViewController.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageDetailViewController.h"
10 |
11 | static const CGFloat ImageDetailZoomMin = 0.2f;
12 | static const CGFloat ImageDetailZoomNormal = 1.0f;
13 | static const CGFloat ImageDetailZoomMax = 5.0f;
14 |
15 | @interface ImageDetailViewController ()
16 |
17 | @property (weak, nonatomic) IBOutlet UINavigationItem *toolbar;
18 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
19 | @property (strong, nonatomic) UIImageView *imageView;
20 |
21 | @end
22 |
23 | @implementation ImageDetailViewController
24 |
25 | #pragma mark - Properties
26 |
27 | - (UIImageView *)imageView
28 | {
29 | if (!_imageView) _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
30 | return _imageView;
31 | }
32 |
33 | - (void)setImageToDisplay:(ImageEntity *)imageToDisplay
34 | {
35 | _imageToDisplay = imageToDisplay;
36 | [self resetImage];
37 | }
38 |
39 | #pragma mark - Methods
40 |
41 | - (void)resetImage
42 | {
43 | if (self.toolbar) {
44 | self.toolbar.title = self.imageToDisplay.title;
45 | }
46 | if (self.scrollView) {
47 | [self resetDisplayArea];
48 | [self displayImage:[self loadImage]];
49 | }
50 | }
51 |
52 | - (void)resetDisplayArea
53 | {
54 | self.scrollView.zoomScale = ImageDetailZoomNormal;
55 | self.scrollView.contentSize = CGSizeZero;
56 | self.imageView.image = nil;
57 | }
58 |
59 | - (UIImage *)loadImage
60 | {
61 | NSData *imageData = [[NSData alloc] initWithContentsOfURL:self.imageToDisplay.formats.normal];
62 | return [[UIImage alloc] initWithData:imageData];
63 | }
64 |
65 | - (void)displayImage:(UIImage *)image
66 | {
67 | if (image) {
68 | self.scrollView.contentSize = image.size;
69 | self.imageView.image = image;
70 | self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
71 | }
72 | }
73 |
74 | - (void)configureScrollView
75 | {
76 | self.scrollView.maximumZoomScale = ImageDetailZoomMax;
77 | self.scrollView.minimumZoomScale = ImageDetailZoomMin;
78 | self.scrollView.delegate = self;
79 | }
80 |
81 | #pragma mark - UIScrollViewDelegate
82 |
83 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
84 | {
85 | return self.imageView;
86 | }
87 |
88 | #pragma mark - UIViewController
89 |
90 | - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
91 | {
92 | /* TODO: Add auto scrolling based on UIScrollView’s bounds and the size of the photo. */
93 | /* See when in the VC's lifecycle you can do geometry calculations with Autolayout on. */
94 | // CGFloat zoomFactor;
95 | // if (self.imageView.image.size.width < self.scrollView.frame.size.width) {
96 | // zoomFactor = self.scrollView.frame.size.width / self.imageView.image.size.width;
97 | // self.scrollView.zoomScale = zoomFactor;
98 | // }
99 | // [self resetImage];
100 | }
101 |
102 | - (void)viewDidLoad
103 | {
104 | [super viewDidLoad];
105 | [self.scrollView addSubview:self.imageView];
106 | [self configureScrollView];
107 | [self resetImage];
108 | }
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/ImageListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageListViewController.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TagEntity.h"
11 |
12 | @interface ImageListViewController : UITableViewController
13 |
14 | @property (strong, nonatomic) NSArray *imageEntries;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/ImageListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageListViewController.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageListViewController.h"
10 | #import "ImageDetailViewController.h"
11 | #import "ImageViewingInteractor.h"
12 | #import "ImageEntity.h"
13 |
14 | static NSString * const ImageListCellReuseIdentifier = @"ImageName";
15 |
16 | @interface ImageListViewController ()
17 |
18 | @end
19 |
20 | @implementation ImageListViewController
21 |
22 | #pragma mark - Properties
23 |
24 | - (void)setImageEntries:(NSArray *)imageEntries
25 | {
26 | _imageEntries = imageEntries;
27 | [self.tableView reloadData];
28 | }
29 |
30 | #pragma mark - UITableViewDataSource
31 |
32 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
33 | {
34 | return (NSInteger)[self.imageEntries count];
35 | }
36 |
37 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
38 | {
39 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ImageListCellReuseIdentifier
40 | forIndexPath:indexPath];
41 | ImageEntity *image = (ImageEntity *)self.imageEntries[(NSUInteger)indexPath.row];
42 | cell.textLabel.text = image.title;
43 | cell.detailTextLabel.text = image.description;
44 | return cell;
45 | }
46 |
47 | #pragma mark - UIViewController
48 |
49 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
50 | {
51 | if ([sender isKindOfClass:[UITableViewCell class]]) {
52 | NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
53 | if (indexPath) {
54 | if ([segue.destinationViewController isKindOfClass:[ImageDetailViewController class]]) {
55 | ImageEntity *image = self.imageEntries[(NSUInteger)indexPath.row];
56 | ((ImageDetailViewController *)segue.destinationViewController).imageToDisplay = image;
57 | }
58 | }
59 | }
60 | }
61 |
62 | - (void)viewDidLoad
63 | {
64 | if (!self.imageEntries) {
65 | self.imageEntries = [[ImageViewingInteractor new] listRecentImages];
66 | }
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/TabletSplitViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TabletSplitViewController.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TabletSplitViewController : UISplitViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/TabletSplitViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TabletSplitViewController.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/24.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "TabletSplitViewController.h"
10 |
11 | @interface TabletSplitViewController ()
12 |
13 | @end
14 |
15 | @implementation TabletSplitViewController
16 |
17 | #pragma mark - NSObject
18 |
19 | - (void)awakeFromNib
20 | {
21 | self.delegate = self;
22 | }
23 |
24 | #pragma mark - UISplitViewControllerDelegate
25 |
26 | -(BOOL)splitViewController:(UISplitViewController *)svc
27 | shouldHideViewController:(UIViewController *)vc
28 | inOrientation:(UIInterfaceOrientation)orientation
29 | {
30 | return NO;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/TagListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // TagListViewController.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TagListViewController : UITableViewController
12 |
13 | @property (strong, nonatomic) NSArray *tagEntries;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Controllers/TagListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // TagListViewController.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "TagListViewController.h"
10 | #import "TagListingInteractor.h"
11 | #import "TagEntity.h"
12 | #import "ImageViewingInteractor.h"
13 |
14 | static NSString * const TagListCellReuseIdentifier = @"TagName";
15 | static NSString * const TagListCellSegueIdentifier = @"ShowImagesForTag";
16 | static NSString * const TagListCellSegueSelector = @"setTagForImages:";
17 | static NSString * const TagListSubtitleText = @"%ld photo%@";
18 |
19 | @interface TagListViewController ()
20 |
21 | @end
22 |
23 | @implementation TagListViewController
24 |
25 | #pragma mark - Properties
26 |
27 | - (void)setTagEntries:(NSArray *)tagEntries
28 | {
29 | _tagEntries = tagEntries;
30 | [self.tableView reloadData];
31 | }
32 |
33 | #pragma mark - Methods
34 |
35 | - (NSArray *)sortAlphabetically:(NSArray *)tagList
36 | {
37 | NSSortDescriptor *byAscendingName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
38 | return [tagList sortedArrayUsingDescriptors:@[byAscendingName]];
39 | }
40 |
41 | #pragma mark - UITableViewDataSource
42 |
43 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
44 | {
45 | return (NSInteger)[self.tagEntries count];
46 | }
47 |
48 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
49 | {
50 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TagListCellReuseIdentifier
51 | forIndexPath:indexPath];
52 | TagEntity *tag = (TagEntity *)self.tagEntries[(NSUInteger)indexPath.row];
53 | BOOL isPlural = tag.numberOfImages > 1;
54 | cell.textLabel.text = tag.description;
55 | cell.detailTextLabel.text = [NSString stringWithFormat:TagListSubtitleText,
56 | (unsigned long)tag.numberOfImages, (isPlural)? @"s" : @""];
57 | return cell;
58 | }
59 |
60 | #pragma mark - UIViewController
61 |
62 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
63 | {
64 | if ([segue.identifier isEqualToString:TagListCellSegueIdentifier]) {
65 | if ([sender isKindOfClass:[UITableViewCell class]]) {
66 | NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
67 | if (indexPath) {
68 | #pragma clang diagnostic push
69 | #pragma clang diagnostic ignored "-Wundeclared-selector"
70 | if ([segue.destinationViewController respondsToSelector:@selector(setImageEntries:)]) {
71 | TagEntity *tag = self.tagEntries[(NSUInteger)indexPath.row];
72 | NSArray * images = [[ImageViewingInteractor new] listImagesByTag:tag];
73 | [segue.destinationViewController performSelector:@selector(setImageEntries:) withObject:images];
74 | }
75 | #pragma clang diagnostic pop
76 | }
77 | }
78 | }
79 | }
80 |
81 | - (void)viewDidLoad
82 | {
83 | [super viewDidLoad];
84 | if (!self.tagEntries) {
85 | NSArray *tagList = [[TagListingInteractor new] listAllTags];
86 | self.tagEntries = [self sortAlphabetically:tagList];
87 | }
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Gateways/ImageSupplierFlickr.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageSupplierFlickr.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ImageSupplierGateway.h"
11 |
12 | @interface ImageSupplierFlickr : NSObject
13 |
14 | + (instancetype)sharedImageSupplierFlickr;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Gateways/ImageSupplierGateway.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageSupplierGateway.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ImageSupplierDataSource.h"
11 |
12 | @interface ImageSupplierGateway : NSObject
13 |
14 | + (id )defaultDataSource;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Adapters/Gateways/ImageSupplierGateway.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageSupplierGateway.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageSupplierGateway.h"
10 | #import "ImageSupplierFlickr.h"
11 |
12 | @implementation ImageSupplierGateway
13 |
14 | + (id)defaultDataSource
15 | {
16 | return [ImageSupplierFlickr sharedImageSupplierFlickr];
17 | }
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // 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.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // 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.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/ImageEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageEntity.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ImageFormatURLs.h"
11 |
12 | @interface ImageEntity : NSObject
13 |
14 | @property (readonly, strong, nonatomic) NSString *title;
15 | @property (readonly, strong, nonatomic) NSString *description;
16 | @property (readonly, strong, nonatomic) NSString *author;
17 | @property (readonly, strong, nonatomic) ImageFormatURLs *formats;
18 |
19 | ///--------------------------------------------------------------------------------
20 | /// @name Initializing an Image
21 | ///--------------------------------------------------------------------------------
22 |
23 | /** Designated initializer. */
24 | - (id)initWithTitle:(NSString *)titleText
25 | description:(NSString *)descriptionText
26 | author:(NSString *)authorName
27 | formats:(ImageFormatURLs *)formatURLs;
28 |
29 | + (id)new __attribute__((unavailable("use the designated initializer instead")));
30 | - (id)init __attribute__((unavailable("use the designated initializer instead")));
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/ImageEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageEntity.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageEntity.h"
10 |
11 | @implementation ImageEntity
12 |
13 | - (id)initWithTitle:(NSString *)titleText
14 | description:(NSString *)descriptionText
15 | author:(NSString *)authorName
16 | formats:(ImageFormatURLs *)formatURLs
17 | {
18 | self = [super init];
19 | if (self) {
20 | _title = titleText;
21 | _description = descriptionText;
22 | _author = authorName;
23 | _formats = formatURLs;
24 | }
25 | return self;
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/ImageFormatURLs.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageFormatURLs.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/13.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageFormatURLs : NSObject
12 |
13 | @property (readonly, strong, nonatomic) NSURL *thumbnail;
14 | @property (readonly, strong, nonatomic) NSURL *normal;
15 | @property (readonly, strong, nonatomic) NSURL *hires;
16 |
17 | ///--------------------------------------------------------------------------------
18 | /// @name Initializing an Image
19 | ///--------------------------------------------------------------------------------
20 |
21 | /** Designated initializer. */
22 | - (id)initWithURL:(NSURL *)normalURL thumbnail:(NSURL *)thumbURL hires:(NSURL *)hiresURL;
23 |
24 | + (id)new __attribute__((unavailable("use the designated initializer instead")));
25 | - (id)init __attribute__((unavailable("use the designated initializer instead")));
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/ImageFormatURLs.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageFormatURLs.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/13.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageFormatURLs.h"
10 |
11 | @implementation ImageFormatURLs
12 |
13 | #pragma mark - Initialization
14 |
15 | - (id)initWithURL:(NSURL *)normalURL thumbnail:(NSURL *)thumbURL hires:(NSURL *)hiresURL
16 | {
17 | self = [super init];
18 | if (self) {
19 | _normal = normalURL;
20 | _thumbnail = thumbURL;
21 | _hires = hiresURL;
22 | }
23 | return self;
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/TagEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // TagEntity.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TagEntity : NSObject
12 |
13 | @property (readonly, strong, nonatomic) NSString *name;
14 | @property (readonly, nonatomic) NSUInteger numberOfImages;
15 |
16 | ///--------------------------------------------------------------------------------
17 | /// @name Initializing a Tag
18 | ///--------------------------------------------------------------------------------
19 |
20 | /** Designated initializer. */
21 | - (id)initWithName:(NSString *)name imageCount:(NSUInteger)count;
22 |
23 | + (id)new __attribute__((unavailable("use the designated initializer instead")));
24 | - (id)init __attribute__((unavailable("use the designated initializer instead")));
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Entities/TagEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // TagEntity.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "TagEntity.h"
10 |
11 | @implementation TagEntity
12 |
13 | #pragma mark - Initialization
14 |
15 | - (id)initWithName:(NSString *)name imageCount:(NSUInteger)count
16 | {
17 | self = [super init];
18 | if (self) {
19 | _name = name;
20 | _numberOfImages = count;
21 | }
22 | return self;
23 | }
24 |
25 | #pragma mark - NSObject
26 |
27 | - (NSString *)description
28 | {
29 | return [self.name capitalizedString];
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Interfaces/FlickrFetcher/FlickrAPIKey.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrAPIKey.h
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University. All rights reserved.
6 | //
7 | // Get your own key!
8 | // No Flickr fetches will work without the API Key!
9 | //
10 |
11 | #define FlickrAPIKey @"9a0554259914a86fb9e7eb014e4e5d52"
12 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Interfaces/FlickrFetcher/FlickrFetcher.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrFetcher.h
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | // tags in the photo dictionaries returned from stanfordPhotos or latestGeoreferencedPhotos
11 |
12 | #define FLICKR_PHOTO_TITLE @"title"
13 | #define FLICKR_PHOTO_DESCRIPTION @"description._content" // must use valueForKeyPath: on this one
14 | #define FLICKR_PLACE_NAME @"_content"
15 | #define FLICKR_PHOTO_ID @"id"
16 | #define FLICKR_LATITUDE @"latitude"
17 | #define FLICKR_LONGITUDE @"longitude"
18 | #define FLICKR_PHOTO_OWNER @"ownername"
19 | #define FLICKR_PHOTO_PLACE_NAME @"derived_place" // doesn't work for Stanford photos
20 | #define FLICKR_TAGS @"tags"
21 |
22 | #define NSLOG_FLICKR NO
23 |
24 | typedef enum {
25 | FlickrPhotoFormatSquare = 1, // 75x75
26 | FlickrPhotoFormatLarge = 2, // 1024x768
27 | FlickrPhotoFormatOriginal = 64 // at least 1024x768
28 | } FlickrPhotoFormat;
29 |
30 | @interface FlickrFetcher : NSObject
31 |
32 | // fetch a bunch of Flickr photo dictionaries using the Flickr API
33 | + (NSArray *)stanfordPhotos;
34 |
35 | // get the URL for a Flickr photo given a dictionary of Flickr photo info
36 | // (which can be gotten using stanfordPhotos or latestGeoreferencedPhotos)
37 | + (NSURL *)urlForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format;
38 |
39 | // fetch a bunch of recently taken georeferenced Flickr photo dictionaries
40 | + (NSArray *)latestGeoreferencedPhotos;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Interfaces/FlickrFetcher/FlickrFetcher.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrFetcher.m
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University. All rights reserved.
6 | //
7 |
8 | #import "FlickrFetcher.h"
9 | #import "FlickrAPIKey.h"
10 |
11 | #define FLICKR_PLACE_ID @"place_id"
12 |
13 | @implementation FlickrFetcher
14 |
15 | + (NSDictionary *)executeFlickrFetch:(NSString *)query
16 | {
17 | query = [NSString stringWithFormat:@"%@&format=json&nojsoncallback=1&api_key=%@", query, FlickrAPIKey];
18 | query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
19 | if (NSLOG_FLICKR) NSLog(@"[%@ %@] sent %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), query);
20 | NSData *jsonData = [[NSString stringWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:nil] dataUsingEncoding:NSUTF8StringEncoding];
21 | NSError *error = nil;
22 | NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;
23 | if (error) NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
24 | if (NSLOG_FLICKR) NSLog(@"[%@ %@] received %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), results);
25 | return results;
26 | }
27 |
28 | + (NSArray *)topPlaces
29 | {
30 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.places.getTopPlacesList&place_type_id=7"];
31 | return [[self executeFlickrFetch:request] valueForKeyPath:@"places.place"];
32 | }
33 |
34 | + (NSArray *)stanfordPhotos
35 | {
36 | NSString *request = @"http://api.flickr.com/services/rest/?user_id=48247111@N07&format=json&nojsoncallback=1&extras=original_format,tags,description,geo,date_upload,owner_name&page=1&method=flickr.photos.search";
37 | return [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
38 | }
39 |
40 | + (NSArray *)photosInPlace:(NSDictionary *)place maxResults:(int)maxResults
41 | {
42 | NSArray *photos = nil;
43 | NSString *placeId = [place objectForKey:FLICKR_PLACE_ID];
44 | if (placeId) {
45 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.photos.search&place_id=%@&per_page=%d&extras=original_format,tags,description,geo,date_upload,owner_name,place_url", placeId, maxResults];
46 | NSString *placeName = [place objectForKey:FLICKR_PLACE_NAME];
47 | photos = [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
48 | for (NSMutableDictionary *photo in photos) {
49 | [photo setObject:placeName forKey:FLICKR_PHOTO_PLACE_NAME];
50 | }
51 | }
52 | return photos;
53 | }
54 |
55 | + (NSArray *)latestGeoreferencedPhotos
56 | {
57 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.photos.search&per_page=500&license=1,2,4,7&has_geo=1&extras=original_format,tags,description,geo,date_upload,owner_name,place_url"];
58 | return [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
59 | }
60 |
61 | + (NSString *)urlStringForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format
62 | {
63 | id farm = [photo objectForKey:@"farm"];
64 | id server = [photo objectForKey:@"server"];
65 | id photo_id = [photo objectForKey:@"id"];
66 | id secret = [photo objectForKey:@"secret"];
67 | if (format == FlickrPhotoFormatOriginal) secret = [photo objectForKey:@"originalsecret"];
68 |
69 | NSString *fileType = @"jpg";
70 | if (format == FlickrPhotoFormatOriginal) fileType = [photo objectForKey:@"originalformat"];
71 |
72 | if (!farm || !server || !photo_id || !secret) return nil;
73 |
74 | NSString *formatString = @"s";
75 | switch (format) {
76 | case FlickrPhotoFormatSquare: formatString = @"s"; break;
77 | case FlickrPhotoFormatLarge: formatString = @"b"; break;
78 | // case FlickrPhotoFormatThumbnail: formatString = @"t"; break;
79 | // case FlickrPhotoFormatSmall: formatString = @"m"; break;
80 | // case FlickrPhotoFormatMedium500: formatString = @"-"; break;
81 | // case FlickrPhotoFormatMedium640: formatString = @"z"; break;
82 | case FlickrPhotoFormatOriginal: formatString = @"o"; break;
83 | }
84 |
85 | return [NSString stringWithFormat:@"http://farm%@.static.flickr.com/%@/%@_%@_%@.%@", farm, server, photo_id, secret, formatString, fileType];
86 | }
87 |
88 | + (NSURL *)urlForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format
89 | {
90 | return [NSURL URLWithString:[self urlStringForPhoto:photo format:format]];
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Interfaces/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Interfaces/Resources/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/SPoT-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | pt.mindclick.cs193p.${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 | UIMainStoryboardFile
28 | iPhonePhotoBrowsing
29 | UIMainStoryboardFile~ipad
30 | iPadPhotoBrowsing
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationLandscapeLeft
45 | UIInterfaceOrientationLandscapeRight
46 | UIInterfaceOrientationPortraitUpsideDown
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/SPoT-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
18 | // Custom definitions
19 | #import "Helpers.h"
20 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Support/Config/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // Debug.xcconfig
3 | //
4 | // Created by Hugo Ferreira on 2013/10/10.
5 | // Copyright (c) 2013 Mindclick. All rights reserved.
6 | //
7 |
8 | #include "Warnings.xcconfig"
9 |
10 | // Override some of the warnings settings
11 | GCC_TREAT_WARNINGS_AS_ERRORS = NO
12 |
13 | // Setup code coverage analysis
14 | // http://blog.nwoolls.com/2013/02/08/visualizing-code-coverage-with-xcode/
15 | GCC_GENERATE_TEST_COVERAGE_FILES = YES
16 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES
17 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Support/Config/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | //
2 | // MoreWarnings.xcconfig
3 | //
4 | // Created by Steven Fisher:
5 | // http://tewha.net/2010/11/xcode-warnings/
6 | // See also:
7 | // http://boredzo.org/blog/archives/2009-11-07/warnings
8 | //
9 |
10 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES
11 | GCC_WARN_SHADOW = YES
12 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES
13 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
14 | GCC_WARN_ABOUT_RETURN_TYPE = YES
15 | GCC_WARN_MISSING_PARENTHESES = YES
16 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES
17 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES
18 | GCC_WARN_SIGN_COMPARE = YES
19 | GCC_WARN_UNDECLARED_SELECTOR = YES
20 | GCC_WARN_UNUSED_FUNCTION = YES
21 | GCC_WARN_UNUSED_LABEL = YES
22 | GCC_WARN_UNUSED_VALUE = YES
23 | GCC_WARN_UNUSED_VARIABLE = YES
24 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES
25 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES
26 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES
27 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES
28 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES
29 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES
30 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES
31 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES
32 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES
33 | OTHER_CFLAGS = -Wextra -Wno-unused-parameter
34 | GCC_TREAT_WARNINGS_AS_ERRORS = YES
35 | RUN_CLANG_STATIC_ANALYZER = YES
36 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Support/Helpers/ArrayCount.h:
--------------------------------------------------------------------------------
1 | /**
2 | "Get the number of elements of an array passed by parameter in C?"
3 | http://stackoverflow.com/a/19415065/1380781
4 | */
5 | #define C_ARRAY_COUNT(array) (sizeof(array)/sizeof(*(array)))
6 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Support/Helpers/Helpers.h:
--------------------------------------------------------------------------------
1 | //
2 | // Helpers.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/13.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #ifndef SPoT_Helpers
10 | #define SPoT_Helpers
11 |
12 | #import "ArrayCount.h"
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Use Cases/ImageSupplierDataSource.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageSupplierDataSource.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/15.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TagEntity.h"
11 |
12 | @protocol ImageSupplierDataSource
13 |
14 | /** @return List of `TagEntity` objects. */
15 | - (NSArray *)listTagsAvailable;
16 |
17 | /**
18 | @param tagsToExclude List of objects defining the ignored tags, evaluated as strings.
19 | @return List of `TagEntity` objects.
20 | */
21 | - (NSArray *)listTagsExcluding:(NSArray *)tagsToExclude;
22 |
23 | /** @return List of `ImageEntity` objects. */
24 | - (NSArray *)listImagesRecentlyUploaded;
25 |
26 | /** @return List of `ImageEntity` objects. */
27 | - (NSArray *)listImagesWithTag:(TagEntity *)tag;
28 |
29 | /** @return List of `ImageEntity` objects. */
30 | - (NSArray *)listMax:(NSUInteger)number imagesWithTag:(TagEntity *)tag;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Use Cases/ImageViewingInteractor.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoViewingInteractor.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TagEntity.h"
11 |
12 | @interface ImageViewingInteractor : NSObject
13 |
14 | - (NSArray *)listImagesByTag:(TagEntity *)tag;
15 | - (NSArray *)listRecentImages;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Use Cases/ImageViewingInteractor.m:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoViewingInteractor.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "ImageViewingInteractor.h"
10 | #import "ImageSupplierGateway.h" /* FIXME: Isn't this breaking the Dependency Rule? */
11 |
12 | @interface ImageViewingInteractor ()
13 |
14 | @property (strong, nonatomic) id photoSupplier;
15 |
16 | @end
17 |
18 | @implementation ImageViewingInteractor
19 |
20 | #pragma mark - Properties
21 |
22 | - (id)photoSupplier
23 | {
24 | if (!_photoSupplier) _photoSupplier = [ImageSupplierGateway defaultDataSource];
25 | return _photoSupplier;
26 | }
27 |
28 | #pragma mark - Methods
29 |
30 | - (NSArray *)listImagesByTag:(TagEntity *)tag
31 | {
32 | return [self.photoSupplier listImagesWithTag:tag];
33 | }
34 |
35 | - (NSArray *)listRecentImages
36 | {
37 | /* TODO: Load from [NSUserDefaults standardUserDefaults] if exists, fetch online otherwise */
38 | NSArray *photos = [self.photoSupplier listImagesRecentlyUploaded];
39 | photos = [self removeDuplicates:photos];
40 | photos = [self sortByMostRecent:photos];
41 | return photos;
42 | }
43 |
44 | - (NSArray *)removeDuplicates:(NSArray *)photos
45 | {
46 | /* TODO: implement this someday (based on FLICKR_PHOTO_ID) */
47 | return photos;
48 | }
49 |
50 | - (NSArray *)sortByMostRecent:(NSArray *)photos
51 | {
52 | /* TODO: implement this someday */
53 | return photos;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Use Cases/TagListingInteractor.h:
--------------------------------------------------------------------------------
1 | //
2 | // TagListingInteractor.h
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TagListingInteractor : NSObject
12 |
13 | - (NSArray *)listAllTags;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/Use Cases/TagListingInteractor.m:
--------------------------------------------------------------------------------
1 | //
2 | // TagListingInteractor.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "TagListingInteractor.h"
10 | #import "ImageSupplierGateway.h" /* FIXME: Isn't this breaking the Dependency Rule? */
11 |
12 | static NSString * const TagListExclusions[] = { @"cs193pspot", @"portrait", @"landscape" };
13 |
14 | @interface TagListingInteractor ()
15 |
16 | @property (strong, nonatomic) id photoSupplier;
17 |
18 | @end
19 |
20 | @implementation TagListingInteractor
21 |
22 | #pragma mark - Properties
23 |
24 | - (id)photoSupplier
25 | {
26 | if (!_photoSupplier) _photoSupplier = [ImageSupplierGateway defaultDataSource];
27 | return _photoSupplier;
28 | }
29 |
30 | #pragma mark - Methods
31 |
32 | - (NSArray *)listAllTags
33 | {
34 | NSArray *tagsToIgnore = [NSArray arrayWithObjects:TagListExclusions count:C_ARRAY_COUNT(TagListExclusions)];
35 | return [self.photoSupplier listTagsExcluding:tagsToIgnore];
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoT/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. 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 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoTTests/FlickrFetcherLearningTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrFetcherLearningTests.m
3 | // SPoT
4 | //
5 | // Created by Hugo Ferreira on 2013/11/12.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "FlickrFetcher.h"
11 |
12 | @interface FlickrFetcherLearningTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation FlickrFetcherLearningTests
17 |
18 | - (void)testStanfordPhotosReturnsTags
19 | {
20 | NSArray *photos = [FlickrFetcher stanfordPhotos];
21 | NSArray *tagsPerPhoto = [photos valueForKey:FLICKR_TAGS];
22 | NSArray *allTagsUsed = [[tagsPerPhoto componentsJoinedByString:@" "] componentsSeparatedByString:@" "];
23 | NSSet *uniqueTagList = [NSSet setWithArray:allTagsUsed];
24 | XCTAssert([uniqueTagList count] < [allTagsUsed count], @"Duplicate tags should have disappeared");
25 | }
26 |
27 | - (void)testRecentPhotosReturnsLimitedSize
28 | {
29 | NSArray *photos = [FlickrFetcher latestGeoreferencedPhotos];
30 | XCTAssertEqual([photos count] <= 250, @"Too many photos received");
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoTTests/SPoTTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | pt.mindclick.cs193p.${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 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoTTests/SPoTTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SPoTTests.m
3 | // SPoTTests
4 | //
5 | // Created by Hugo Ferreira on 2013/11/07.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SPoTTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SPoTTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/2013 Winter/SPoT/SPoTTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // 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.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // 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.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Shutterbug/Shutterbug/Default-568h@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Shutterbug/Shutterbug/Default.png
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/Shutterbug/Shutterbug/Default@2x.png
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/FlickrFetcher/FlickrAPIKey.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrAPIKey.h
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University
6 | // All rights reserved.
7 | //
8 | // Get your own key!
9 | // No Flickr fetches will work without the API Key!
10 | //
11 |
12 | #define FlickrAPIKey @"9a0554259914a86fb9e7eb014e4e5d52"
13 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/FlickrFetcher/FlickrFetcher.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrFetcher.h
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University
6 | // All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | // tags in the photo dictionaries returned from stanfordPhotos or latestGeoreferencedPhotos
12 |
13 | #define FLICKR_PHOTO_TITLE @"title"
14 | #define FLICKR_PHOTO_DESCRIPTION @"description._content" // must use valueForKeyPath: on this one
15 | #define FLICKR_PLACE_NAME @"_content"
16 | #define FLICKR_PHOTO_ID @"id"
17 | #define FLICKR_LATITUDE @"latitude"
18 | #define FLICKR_LONGITUDE @"longitude"
19 | #define FLICKR_PHOTO_OWNER @"ownername"
20 | #define FLICKR_PHOTO_PLACE_NAME @"derived_place" // doesn't work for Stanford photos
21 | #define FLICKR_TAGS @"tags"
22 |
23 | #define NSLOG_FLICKR NO
24 |
25 | typedef enum {
26 | FlickrPhotoFormatSquare = 1, // 75x75
27 | FlickrPhotoFormatLarge = 2, // 1024x768
28 | FlickrPhotoFormatOriginal = 64 // at least 1024x768
29 | } FlickrPhotoFormat;
30 |
31 | @interface FlickrFetcher : NSObject
32 |
33 | // fetch a bunch of Flickr photo dictionaries using the Flickr API
34 | + (NSArray *)stanfordPhotos;
35 |
36 | // get the URL for a Flickr photo given a dictionary of Flickr photo info
37 | // (which can be gotten using stanfordPhotos or latestGeoreferencedPhotos)
38 | + (NSURL *)urlForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format;
39 |
40 | // fetch a bunch of recently taken georeferenced Flickr photo dictionaries
41 | + (NSArray *)latestGeoreferencedPhotos;
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/FlickrFetcher/FlickrFetcher.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrFetcher.m
3 | //
4 | // Created for Stanford CS193p Winter 2013.
5 | // Copyright 2013 Stanford University
6 | // All rights reserved.
7 | //
8 |
9 | #import "FlickrFetcher.h"
10 | #import "FlickrAPIKey.h"
11 |
12 | #define FLICKR_PLACE_ID @"place_id"
13 |
14 | @implementation FlickrFetcher
15 |
16 | + (NSDictionary *)executeFlickrFetch:(NSString *)query
17 | {
18 | query = [NSString stringWithFormat:@"%@&format=json&nojsoncallback=1&api_key=%@", query, FlickrAPIKey];
19 | query = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
20 | if (NSLOG_FLICKR) NSLog(@"[%@ %@] sent %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), query);
21 | NSData *jsonData = [[NSString stringWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:nil] dataUsingEncoding:NSUTF8StringEncoding];
22 | NSError *error = nil;
23 | NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;
24 | if (error) NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);
25 | if (NSLOG_FLICKR) NSLog(@"[%@ %@] received %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), results);
26 | return results;
27 | }
28 |
29 | + (NSArray *)topPlaces
30 | {
31 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.places.getTopPlacesList&place_type_id=7"];
32 | return [[self executeFlickrFetch:request] valueForKeyPath:@"places.place"];
33 | }
34 |
35 | + (NSArray *)stanfordPhotos
36 | {
37 | NSString *request = @"http://api.flickr.com/services/rest/?user_id=48247111@N07&format=json&nojsoncallback=1&extras=original_format,tags,description,geo,date_upload,owner_name&page=1&method=flickr.photos.search";
38 | return [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
39 | }
40 |
41 | + (NSArray *)photosInPlace:(NSDictionary *)place maxResults:(int)maxResults
42 | {
43 | NSArray *photos = nil;
44 | NSString *placeId = [place objectForKey:FLICKR_PLACE_ID];
45 | if (placeId) {
46 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.photos.search&place_id=%@&per_page=%d&extras=original_format,tags,description,geo,date_upload,owner_name,place_url", placeId, maxResults];
47 | NSString *placeName = [place objectForKey:FLICKR_PLACE_NAME];
48 | photos = [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
49 | for (NSMutableDictionary *photo in photos) {
50 | [photo setObject:placeName forKey:FLICKR_PHOTO_PLACE_NAME];
51 | }
52 | }
53 | return photos;
54 | }
55 |
56 | + (NSArray *)latestGeoreferencedPhotos
57 | {
58 | NSString *request = [NSString stringWithFormat:@"http://api.flickr.com/services/rest/?method=flickr.photos.search&per_page=500&license=1,2,4,7&has_geo=1&extras=original_format,tags,description,geo,date_upload,owner_name,place_url"];
59 | return [[self executeFlickrFetch:request] valueForKeyPath:@"photos.photo"];
60 | }
61 |
62 | + (NSString *)urlStringForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format
63 | {
64 | id farm = [photo objectForKey:@"farm"];
65 | id server = [photo objectForKey:@"server"];
66 | id photo_id = [photo objectForKey:@"id"];
67 | id secret = [photo objectForKey:@"secret"];
68 | if (format == FlickrPhotoFormatOriginal) secret = [photo objectForKey:@"originalsecret"];
69 |
70 | NSString *fileType = @"jpg";
71 | if (format == FlickrPhotoFormatOriginal) fileType = [photo objectForKey:@"originalformat"];
72 |
73 | if (!farm || !server || !photo_id || !secret) return nil;
74 |
75 | NSString *formatString = @"s";
76 | switch (format) {
77 | case FlickrPhotoFormatSquare: formatString = @"s"; break;
78 | case FlickrPhotoFormatLarge: formatString = @"b"; break;
79 | // case FlickrPhotoFormatThumbnail: formatString = @"t"; break;
80 | // case FlickrPhotoFormatSmall: formatString = @"m"; break;
81 | // case FlickrPhotoFormatMedium500: formatString = @"-"; break;
82 | // case FlickrPhotoFormatMedium640: formatString = @"z"; break;
83 | case FlickrPhotoFormatOriginal: formatString = @"o"; break;
84 | }
85 |
86 | return [NSString stringWithFormat:@"http://farm%@.static.flickr.com/%@/%@_%@_%@.%@", farm, server, photo_id, secret, formatString, fileType];
87 | }
88 |
89 | + (NSURL *)urlForPhoto:(NSDictionary *)photo format:(FlickrPhotoFormat)format
90 | {
91 | return [NSURL URLWithString:[self urlStringForPhoto:photo format:format]];
92 | }
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/FlickrPhotoTVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrPhotoTVC.h
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 | // Will call setImageURL: as part of any "Show Image" segue.
9 |
10 | #import
11 |
12 | @interface FlickrPhotoTVC : UITableViewController
13 |
14 | // the Model for this VC
15 | // an array of dictionaries of Flickr information
16 | // obtained using Flickr API
17 | // (e.g. FlickrFetcher will obtain such an array of dictionaries)
18 | @property (nonatomic, strong) NSArray *photos; // of NSDictionary
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/FlickrPhotoTVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlickrPhotoTVC.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "FlickrPhotoTVC.h"
10 | #import "FlickrFetcher.h"
11 |
12 | @implementation FlickrPhotoTVC
13 |
14 | // sets the Model
15 | // reloads the UITableView (since Model is changing)
16 |
17 | - (void)setPhotos:(NSArray *)photos
18 | {
19 | _photos = photos;
20 | [self.tableView reloadData];
21 | }
22 |
23 | #pragma mark - Segue
24 |
25 | // prepares for the "Show Image" segue by seeing if the destination view controller of the segue
26 | // understands the method "setImageURL:"
27 | // if it does, it sends setImageURL: to the destination view controller with
28 | // the URL of the photo that was selected in the UITableView as the argument
29 | // also sets the title of the destination view controller to the photo's title
30 |
31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
32 | {
33 | if ([sender isKindOfClass:[UITableViewCell class]]) {
34 | NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
35 | if (indexPath) {
36 | if ([segue.identifier isEqualToString:@"Show Image"]) {
37 | if ([segue.destinationViewController respondsToSelector:@selector(setImageURL:)]) {
38 | NSURL *url = [FlickrFetcher urlForPhoto:self.photos[indexPath.row] format:FlickrPhotoFormatLarge];
39 | [segue.destinationViewController performSelector:@selector(setImageURL:) withObject:url];
40 | [segue.destinationViewController setTitle:[self titleForRow:indexPath.row]];
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
47 | #pragma mark - UITableViewDataSource
48 |
49 | // lets the UITableView know how many rows it should display
50 | // in this case, just the count of dictionaries in the Model's array
51 |
52 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
53 | {
54 | return [self.photos count];
55 | }
56 |
57 | // a helper method that looks in the Model for the photo dictionary at the given row
58 | // and gets the title out of it
59 |
60 | - (NSString *)titleForRow:(NSUInteger)row
61 | {
62 | return [self.photos[row][FLICKR_PHOTO_TITLE] description]; // description because could be NSNull
63 | }
64 |
65 | // a helper method that looks in the Model for the photo dictionary at the given row
66 | // and gets the owner of the photo out of it
67 |
68 | - (NSString *)subtitleForRow:(NSUInteger)row
69 | {
70 | return [self.photos[row][FLICKR_PHOTO_OWNER] description]; // description because could be NSNull
71 | }
72 |
73 | // loads up a table view cell with the title and owner of the photo at the given row in the Model
74 |
75 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
76 | {
77 | static NSString *CellIdentifier = @"Flickr Photo";
78 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
79 |
80 | // Configure the cell...
81 | cell.textLabel.text = [self titleForRow:indexPath.row];
82 | cell.detailTextLabel.text = [self subtitleForRow:indexPath.row];
83 |
84 | return cell;
85 | }
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/HawaiiImageViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HawaiiImageViewController.h
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "ImageViewController.h"
10 |
11 | @interface HawaiiImageViewController : ImageViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/HawaiiImageViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HawaiiImageViewController.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "HawaiiImageViewController.h"
10 |
11 | @implementation HawaiiImageViewController
12 |
13 | // purpose of this entire VC is just to set its Model to a particular photo
14 |
15 | - (void)viewDidLoad
16 | {
17 | [super viewDidLoad];
18 | self.imageURL = [[NSURL alloc] initWithString:@"http://images.apple.com/v/iphone/gallery/a/images/photo_3.jpg"];
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/ImageViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ImageViewController.h
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageViewController : UIViewController
12 |
13 | // the Model for this VC
14 | // simply the URL of a UIImage-compatible image (jpg, png, etc.)
15 | @property (nonatomic, strong) NSURL *imageURL;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/ImageViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageViewController.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "ImageViewController.h"
10 |
11 | @interface ImageViewController ()
12 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
13 | @property (strong, nonatomic) UIImageView *imageView;
14 | @end
15 |
16 | @implementation ImageViewController
17 |
18 | // resets the image whenever the URL changes
19 |
20 | - (void)setImageURL:(NSURL *)imageURL
21 | {
22 | _imageURL = imageURL;
23 | [self resetImage];
24 | }
25 |
26 | // fetches the data from the URL
27 | // turns it into an image
28 | // adjusts the scroll view's content size to fit the image
29 | // sets the image as the image view's image
30 |
31 | - (void)resetImage
32 | {
33 | if (self.scrollView) {
34 | self.scrollView.contentSize = CGSizeZero;
35 | self.imageView.image = nil;
36 |
37 | NSData *imageData = [[NSData alloc] initWithContentsOfURL:self.imageURL];
38 | UIImage *image = [[UIImage alloc] initWithData:imageData];
39 | if (image) {
40 | self.scrollView.zoomScale = 1.0;
41 | self.scrollView.contentSize = image.size;
42 | self.imageView.image = image;
43 | self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height);
44 | }
45 | }
46 | }
47 |
48 | // lazy instantiation
49 |
50 | - (UIImageView *)imageView
51 | {
52 | if (!_imageView) _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
53 | return _imageView;
54 | }
55 |
56 | // returns the view which will be zoomed when the user pinches
57 | // in this case, it is the image view, obviously
58 | // (there are no other subviews of the scroll view in its content area)
59 |
60 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
61 | {
62 | return self.imageView;
63 | }
64 |
65 | // add the image view to the scroll view's content area
66 | // setup zooming by setting min and max zoom scale
67 | // and setting self to be the scroll view's delegate
68 | // resets the image in case URL was set before outlets (e.g. scroll view) were set
69 |
70 | - (void)viewDidLoad
71 | {
72 | [super viewDidLoad];
73 | [self.scrollView addSubview:self.imageView];
74 | self.scrollView.minimumZoomScale = 0.2;
75 | self.scrollView.maximumZoomScale = 5.0;
76 | self.scrollView.delegate = self;
77 | [self resetImage];
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/LatestFlickrPhotosTVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // LatestFlickrPhotosTVC.h
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "FlickrPhotoTVC.h"
10 |
11 | @interface LatestFlickrPhotosTVC : FlickrPhotoTVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/LatestFlickrPhotosTVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // LatestFlickrPhotosTVC.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. All rights reserved.
7 | //
8 |
9 | #import "LatestFlickrPhotosTVC.h"
10 | #import "FlickrFetcher.h"
11 |
12 | @implementation LatestFlickrPhotosTVC
13 |
14 | // purpose of this entire VC is just to set its Model by querying Flickr using FlickrFetcher
15 |
16 | - (void)viewDidLoad
17 | {
18 | [super viewDidLoad];
19 | self.photos = [FlickrFetcher latestGeoreferencedPhotos];
20 | }
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/Shutterbug-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | edu.stanford.cs193p.instructor.${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 | UIMainStoryboardFile
28 | MainStoryboard
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/Shutterbug-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'Shutterbug' target in the 'Shutterbug' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/Shutterbug/Shutterbug/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Shutterbug
4 | //
5 | // Created by CS193p Instructor.
6 | // Copyright (c) 2013 Stanford University. 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 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♠.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "J♠.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "J♠@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♠.imageset/J♠.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♠.imageset/J♠.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♠.imageset/J♠@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♠.imageset/J♠@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♣.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "J♣.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "J♣@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♣.imageset/J♣.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♣.imageset/J♣.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♣.imageset/J♣@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♣.imageset/J♣@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♥.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "J♥.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "J♥@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♥.imageset/J♥.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♥.imageset/J♥.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♥.imageset/J♥@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♥.imageset/J♥@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♦.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "J♦.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "J♦@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♦.imageset/J♦.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♦.imageset/J♦.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♦.imageset/J♦@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/J♦.imageset/J♦@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♠.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "K♠.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "K♠@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♠.imageset/K♠.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♠.imageset/K♠.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♠.imageset/K♠@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♠.imageset/K♠@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♣.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "K♣.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "K♣@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♣.imageset/K♣.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♣.imageset/K♣.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♣.imageset/K♣@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♣.imageset/K♣@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♥.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "K♥.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "K♥@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♥.imageset/K♥.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♥.imageset/K♥.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♥.imageset/K♥@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♥.imageset/K♥@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♦.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "K♦.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "K♦@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♦.imageset/K♦.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♦.imageset/K♦.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♦.imageset/K♦@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/K♦.imageset/K♦@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♠.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Q♠.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Q♠@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♠.imageset/Q♠.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♠.imageset/Q♠.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♠.imageset/Q♠@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♠.imageset/Q♠@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♣.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Q♣.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Q♣@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♣.imageset/Q♣.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♣.imageset/Q♣.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♣.imageset/Q♣@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♣.imageset/Q♣@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♥.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Q♥.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Q♥@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♥.imageset/Q♥.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♥.imageset/Q♥.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♥.imageset/Q♥@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♥.imageset/Q♥@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♦.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Q♦.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Q♦@2x.png"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♦.imageset/Q♦.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♦.imageset/Q♦.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♦.imageset/Q♦@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/Face Cards/Q♦.imageset/Q♦@2x.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/cardback.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "cardback.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/Images.xcassets/cardback.imageset/cardback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hugocf/stanford-cs193p-ios/2f49e8735831b076cf2e672adce4a9312bb8e733/2013 Winter/SuperCard/SuperCard/Images.xcassets/cardback.imageset/cardback.png
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/PlayingCardView.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayingCardView.h
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PlayingCardView : UIView
12 |
13 | @property (nonatomic) NSUInteger rank;
14 | @property (strong, nonatomic) NSString *suit;
15 | @property (nonatomic, getter = isFaceUp) BOOL faceUp;
16 |
17 | - (void)pinch:(UIGestureRecognizer *)gesture;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCard-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | pt.mindclick.${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 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCard-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCardAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SuperCardAppDelegate.h
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SuperCardAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCardAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // SuperCardAppDelegate.m
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "SuperCardAppDelegate.h"
10 |
11 | @implementation SuperCardAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // 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.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // 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.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCardViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SuperCardViewController.h
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SuperCardViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/SuperCardViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SuperCardViewController.m
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import "SuperCardViewController.h"
10 | #import "PlayingCardView.h"
11 |
12 | @interface SuperCardViewController ()
13 | @property (weak, nonatomic) IBOutlet PlayingCardView *playingCard;
14 | @end
15 |
16 | @implementation SuperCardViewController
17 |
18 | #pragma mark - Properties
19 |
20 | - (void)setPlayingCard:(PlayingCardView *)playingCard
21 | {
22 | _playingCard = playingCard;
23 | // TODO: Import Matchismo model and draw a random paying card every time it flips
24 | playingCard.rank = 13; // K
25 | playingCard.suit = @"♥";
26 | [playingCard addGestureRecognizer:[[UIPinchGestureRecognizer alloc] initWithTarget:self.playingCard
27 | action:@selector(pinch:)]];
28 | }
29 |
30 | #pragma mark - Methods
31 |
32 | - (IBAction)swipeCard:(UISwipeGestureRecognizer *)sender
33 | {
34 | [UIView transitionWithView:self.playingCard
35 | duration:0.5
36 | options:UIViewAnimationOptionTransitionFlipFromLeft
37 | animations:^{
38 | self.playingCard.faceUp = !self.playingCard.isFaceUp;
39 | }
40 | completion:nil];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCard/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SuperCard
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "SuperCardAppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SuperCardAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCardTests/SuperCardTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | pt.mindclick.${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 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCardTests/SuperCardTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SuperCardTests.m
3 | // SuperCardTests
4 | //
5 | // Created by Hugo Ferreira on 2013/09/26.
6 | // Copyright (c) 2013 Mindclick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SuperCardTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SuperCardTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/2013 Winter/SuperCard/SuperCardTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stanford CS193P - iPad and iPhone Application Development
2 | *by Paul Hegarty*
3 |
4 | ## Stanford's class page
5 |
6 | * [CS 193P iPhone Application Development](http://cs193p.stanford.edu/)
7 |
8 | ## 2014-15 Winter
9 |
10 | Updated for iOS 8 and Swift.
11 |
12 | * Stanford's [Downloads (2014-15 Winter)](http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2015-winter)
13 | * *2015-02-08: Course still in progress… See the [main Stanford’s class page](http://cs193p.stanford.edu/) for the supporting materials.*
14 | * iTunes U: [Developing iOS 8 Apps with Swift](https://itunes.apple.com/us/course/developing-ios-8-apps-swift/id961180099)
15 |
16 | ## 2013-14 Fall
17 |
18 | Updated for iOS 7.
19 |
20 | * Stanford's [Downloads (2013-14 Fall)](http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2013-fall)
21 | * iTunes U: [Developing iOS 7 Apps for iPhone and iPad](https://itunes.apple.com/en/course/developing-ios-7-apps-for/id733644550)
22 |
23 | ## 2012-13 Winter
24 |
25 | Updated for iOS 6.
26 |
27 | * Stanford's [Downloads (2012-13 Winter)](http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2013-winter)
28 | * iTunes U: [Coding Together: Developing Apps for iPhone and iPad (Winter 2013)](https://itunes.apple.com/en/course/coding-together-developing/id593208016)
29 |
30 | ## 2011-12 Fall
31 |
32 | Learn how to create iOS 5 apps.
33 |
34 | * Stanford's [Downloads (2011-12 Fall)](http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2011-fall)
35 | * iTunes U: [iPad and iPhone Application Development (HD) iTunes](http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255?mt=10)
36 |
37 |
--------------------------------------------------------------------------------