├── PodioExpenses ├── en.lproj │ └── InfoPlist.strings ├── PELoginViewController.h ├── PEExpensesViewController.h ├── PEAppDelegate.h ├── main.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── PodioExpenses-Prefix.pch ├── PEConfig.h ├── PEAddExpenseViewController.h ├── PELoginViewController.m ├── PodioExpenses-Info.plist ├── PEAppDelegate.m ├── PEAddExpenseViewController.m ├── PEExpensesViewController.m └── Base.lproj │ └── Main.storyboard ├── Docs └── Images │ ├── AddExpense.png │ └── ExpensesList.png ├── Podfile ├── PodioExpenses.xcworkspace └── contents.xcworkspacedata ├── Podfile.lock ├── .gitignore ├── LICENSE ├── README.md └── PodioExpenses.xcodeproj └── project.pbxproj /PodioExpenses/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Docs/Images/AddExpense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/podio/sample-ios-expenses/master/Docs/Images/AddExpense.png -------------------------------------------------------------------------------- /Docs/Images/ExpensesList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/podio/sample-ios-expenses/master/Docs/Images/ExpensesList.png -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, "7.0" 2 | 3 | target "PodioExpenses" do 4 | pod 'PodioKit', :git => 'https://github.com/podio/podio-objc.git', :branch => 'master' 5 | pod 'SVProgressHUD' 6 | end 7 | -------------------------------------------------------------------------------- /PodioExpenses.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /PodioExpenses/PELoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PELoginViewController.h 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PELoginViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PodioExpenses/PEExpensesViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PEExpensesViewController.h 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PEExpensesViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PodioExpenses/PEAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PEAppDelegate.h 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 13/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PEAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PodioExpenses/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 13/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "PEAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PEAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PodioExpenses/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 | } -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - PodioKit (2.0.0-beta5) 3 | - SVProgressHUD (1.0) 4 | 5 | DEPENDENCIES: 6 | - PodioKit (from `https://github.com/podio/podio-objc.git`, branch `master`) 7 | - SVProgressHUD 8 | 9 | EXTERNAL SOURCES: 10 | PodioKit: 11 | :branch: master 12 | :git: https://github.com/podio/podio-objc.git 13 | 14 | SPEC CHECKSUMS: 15 | PodioKit: 074cfe9a6929611a6a12a8e1943caea66106d17d 16 | SVProgressHUD: 5034c6e22b8c2ca3e09402e48d41ed0340aa1c50 17 | 18 | COCOAPODS: 0.33.1 19 | -------------------------------------------------------------------------------- /PodioExpenses/PodioExpenses-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 | #import 17 | #import "PEConfig.h" 18 | #endif 19 | -------------------------------------------------------------------------------- /PodioExpenses/PEConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // PEConfig.h 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | // Generate a Podio API key and update the lines below, see https://developers.podio.com/api-key 10 | #define PODIO_KEY @"your-api-key" 11 | #define PODIO_SECRET @"your-api-secret" 12 | 13 | // The app ID of your expenses app. The app must have a title field and a field with the label "amount". 14 | #define PODIO_APP_ID 999999 -------------------------------------------------------------------------------- /PodioExpenses/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 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build 3 | DerivedData/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | !default.xcworkspace 13 | project.xcworkspace 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | 19 | .DS_Store? 20 | 21 | # Thumbnails 22 | ._* 23 | 24 | # Files that might appear on external disk 25 | .Spotlight-V100 26 | .Trashes 27 | .DS_Store 28 | 29 | # opendiff merge 30 | *.BASE.* 31 | *.LOCAL.* 32 | *.REMOTE.* 33 | *.BACKUP.* 34 | *.orig 35 | 36 | # AppCode 37 | .idea 38 | 39 | # CocoaPods 40 | Pods/* 41 | 42 | # Project 43 | Archives/* -------------------------------------------------------------------------------- /PodioExpenses/PEAddExpenseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PEAddExpenseTableViewController.h 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PEAddExpenseViewController; 12 | 13 | @protocol PEAddExpenseViewControllerDelegate 14 | 15 | - (void)addExpenseController:(PEAddExpenseViewController *)controller didAddExpense:(PKTItem *)expense; 16 | 17 | @end 18 | 19 | @interface PEAddExpenseViewController : UITableViewController 20 | 21 | @property (nonatomic, weak) id delegate; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Copyright Citrix Systems, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to 8 | do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /PodioExpenses/PELoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PELoginViewController.m 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PELoginViewController.h" 11 | 12 | @interface PELoginViewController () 13 | 14 | @property (weak, nonatomic) IBOutlet UITextField *emailTextField; 15 | @property (weak, nonatomic) IBOutlet UITextField *passwordTextField; 16 | 17 | @end 18 | 19 | @implementation PELoginViewController 20 | 21 | - (IBAction)login { 22 | // Normally you would perform some kind of validation here, but we will skip it for this sample app. 23 | NSString *email = self.emailTextField.text; 24 | NSString *password = self.passwordTextField.text; 25 | 26 | [SVProgressHUD showWithStatus:@"Signing in..."]; 27 | 28 | // This will authenticate the user agains the Podio API and maintain a session token 29 | [[PodioKit authenticateAsUserWithEmail:email password:password] onSuccess:^(id result) { 30 | [SVProgressHUD dismiss]; 31 | NSLog(@"Successfully authenticated"); 32 | } onError:^(NSError *error) { 33 | [SVProgressHUD dismiss]; 34 | NSLog(@"Error: %@", [error localizedDescription]); 35 | }]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /PodioExpenses/PodioExpenses-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.podio.${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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Podio Expenses 2 | 3 | *Podio Expenses* is an iPhone app for reporting expense built using [PodioKit](https://github.com/podio/podio-objc), the Podio Objective-C library. It is meant to demonstrate the functionality of PodioKit and serve as a reference implementation. 4 | 5 | ![List of expenses](Docs/Images/ExpensesList.png) ![Add an expense](Docs/Images/AddExpense.png) 6 | 7 | ## Run the app 8 | 9 | Before you can run the app, you need to setup your own API key and secret as well as the Podio app to use as a backend for the iOS app. 10 | 11 | ### 1. Generate a Podio API key and secret 12 | To generate a Podio API key and secret, use [this guide](https://developers.podio.com/api-key). 13 | 14 | ### 2. Create the backend Podio app 15 | Now you need to create a [Podio app](https://developers.podio.com/doc/applications) to use as the backend for this iOS app. Go to your Podio account on on the web and create a new app called *Expenses* in any workspace. This app will contain all expenses created from the iOS app in the form of Podio [items](https://developers.podio.com/doc/items). 16 | 17 | Add two fields to the app: 18 | 19 | * A **Text** field called *Title* 20 | * A **Money** field called *Amount* 21 | * An **Image** field called *Receipt* 22 | 23 | Each expense created will need to provide a value for each of these fields. 24 | 25 | Once your app is created, find out its app ID by clicking the small wrench icon to the top right of your app and selecting the "Developer" option in the drop down menu. 26 | 27 | ### 3. Build and run 28 | This project uses [CocoaPods](http://cocoapods.org/) to install 3rd party dependencies, including PodioKit. In order to run it, you need to first have CocoaPods installed and then run the following command from the project root directory: 29 | 30 | ```shell 31 | $ pod install 32 | ``` 33 | 34 | Finally, you need to update the [PEConfig.h](PodioExpenses/PEConfig.h) file in the project with your API key, secret and app ID. 35 | 36 | That's it. You should now be able to build and run the app on a device or simulator. 37 | 38 | ## Credits 39 | 40 | This project uses a few open source components through CocoaPods: 41 | 42 | * [**FXKeychain**](https://github.com/nicklockwood/FXKeychain) An easy to use Keychain wrapper. 43 | * [**SVProgressHUD**](https://github.com/samvermette/SVProgressHUD) A convenient Progress HUD implementation. -------------------------------------------------------------------------------- /PodioExpenses/PEAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // PEAppDelegate.m 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 13/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import "PEAppDelegate.h" 10 | 11 | static NSString * const kTokenKey = @"PodioExpensesToken"; 12 | 13 | @interface PEAppDelegate () 14 | 15 | @property (nonatomic, weak) UINavigationController *loginNavController; 16 | 17 | @end 18 | 19 | @implementation PEAppDelegate 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | // In order to talk to the Podio API, PodioKit needs to know your API key and secret. 23 | // For more info, see https://developers.podio.com/api-key 24 | [PodioKit setupWithAPIKey:PODIO_KEY secret:PODIO_SECRET]; 25 | 26 | // We want the user session to persist across application lauches so we will tell PodioKit 27 | // to store and manage the token in the keychain for us. 28 | [PodioKit automaticallyStoreTokenInKeychainForCurrentApp]; 29 | 30 | [self setupNotifications]; 31 | 32 | return YES; 33 | } 34 | 35 | - (void)applicationDidBecomeActive:(UIApplication *)application { 36 | [self updateLoginScreen]; 37 | } 38 | 39 | #pragma mark - Private 40 | 41 | - (void)setupNotifications { 42 | [[NSNotificationCenter defaultCenter] addObserver:self 43 | selector:@selector(sessionDidChange:) 44 | name:PKTClientAuthenticationStateDidChangeNotification 45 | object:nil]; 46 | } 47 | 48 | - (void)updateLoginScreen { 49 | if ([PodioKit isAuthenticated] && self.loginNavController) { 50 | // Authenticated but the login screen is still showing. Hide it. 51 | [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; 52 | self.loginNavController = nil; 53 | } else if (![PodioKit isAuthenticated] && !self.loginNavController) { 54 | // Not authenticated but we are not displaying a login screen. Show it. 55 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 56 | self.loginNavController = [storyboard instantiateViewControllerWithIdentifier:@"LoginNavController"]; 57 | 58 | [self.window.rootViewController presentViewController:self.loginNavController animated:NO completion:nil]; 59 | } 60 | } 61 | 62 | #pragma mark - Notifications 63 | 64 | - (void)sessionDidChange:(NSNotification *)notification { 65 | // If the session changed we need to check if we need to show the login screen again. 66 | [self updateLoginScreen]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /PodioExpenses/PEAddExpenseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PEAddExpenseTableViewController.m 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PEAddExpenseViewController.h" 11 | 12 | static NSString * const kPhotoImageName = @"Receipt.jpg"; 13 | 14 | @interface PEAddExpenseViewController () 15 | 16 | @property (weak, nonatomic) IBOutlet UITextField *titleTextField; 17 | @property (weak, nonatomic) IBOutlet UITextField *amountTextField; 18 | @property (nonatomic, strong) UIImage *photoImage; 19 | @property (weak, nonatomic) IBOutlet UILabel *photoLabel; 20 | 21 | @end 22 | 23 | @implementation PEAddExpenseViewController 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | 28 | [self updatePhotoLabel]; 29 | } 30 | 31 | #pragma mark Actions 32 | 33 | - (IBAction)saveExpense { 34 | NSString *title = self.titleTextField.text; 35 | NSNumber *amountValue = @([self.amountTextField.text floatValue]); 36 | PKTMoney *amount = [[PKTMoney alloc] initWithAmount:amountValue currency:@"USD"]; 37 | 38 | [SVProgressHUD showWithStatus:@"Saving expense..."]; 39 | 40 | PEAddExpenseViewController __weak *weakSelf = self; 41 | 42 | // First, upload the image file 43 | NSData *imageData = UIImageJPEGRepresentation(self.photoImage, 0.8f); 44 | [[[PKTFile uploadWithData:imageData fileName:kPhotoImageName] pipe:^PKTAsyncTask *(PKTFile *file) { 45 | [SVProgressHUD dismiss]; 46 | 47 | PKTItem *item = [PKTItem itemForAppWithID:PODIO_APP_ID]; 48 | item[@"title"] = title; 49 | item[@"amount"] = amount; 50 | item[@"receipt"] = file; 51 | 52 | return [item save]; 53 | }] onSuccess:^(PKTItem *item) { 54 | [weakSelf didAddExpense:item]; 55 | 56 | [SVProgressHUD dismiss]; 57 | } onError:^(NSError *error) { 58 | [SVProgressHUD showErrorWithStatus:@"Failed to save expense."]; 59 | }]; 60 | } 61 | 62 | - (IBAction)addPhoto:(id)sender { 63 | UIImagePickerController *controller = [[UIImagePickerController alloc] init]; 64 | controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 65 | controller.delegate = self; 66 | 67 | [self presentViewController:controller animated:YES completion:nil]; 68 | } 69 | 70 | #pragma mark - Private 71 | 72 | - (void)updatePhotoLabel { 73 | self.photoLabel.text = self.photoImage ? kPhotoImageName : @"Add photo of receipt..."; 74 | } 75 | 76 | - (void)didAddExpense:(PKTItem *)item { 77 | if ([self.delegate respondsToSelector:@selector(addExpenseController:didAddExpense:)]) { 78 | [self.delegate addExpenseController:self didAddExpense:item]; 79 | } 80 | } 81 | 82 | #pragma mark - UIImagePickerControllerDelegate 83 | 84 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 85 | self.photoImage = info[UIImagePickerControllerOriginalImage]; 86 | [self updatePhotoLabel]; 87 | 88 | [self dismissViewControllerAnimated:YES completion:nil]; 89 | } 90 | 91 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { 92 | [self dismissViewControllerAnimated:YES completion:nil]; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /PodioExpenses/PEExpensesViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PEExpensesViewController.m 3 | // PodioExpenses 4 | // 5 | // Created by Sebastian Rehnby on 14/05/14. 6 | // Copyright (c) 2014 Citrix Systems, Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PEExpensesViewController.h" 11 | #import "PEAddExpenseViewController.h" 12 | 13 | static NSNumberFormatter *moneyFormatter = nil; 14 | 15 | @interface PEExpensesViewController () 16 | 17 | @property (nonatomic, copy) NSArray *expenses; 18 | 19 | @end 20 | 21 | @implementation PEExpensesViewController 22 | 23 | + (void)initialize { 24 | if (self == [PEExpensesViewController class]) { 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | moneyFormatter = [[NSNumberFormatter alloc] init]; 28 | moneyFormatter.numberStyle = NSNumberFormatterDecimalStyle; 29 | }); 30 | } 31 | } 32 | 33 | #pragma mark - UIViewController 34 | 35 | - (void)viewWillAppear:(BOOL)animated { 36 | [super viewWillAppear:animated]; 37 | 38 | [self refreshExpenses]; 39 | } 40 | 41 | #pragma mark - Private 42 | 43 | - (IBAction)refreshExpenses { 44 | if (![PodioKit isAuthenticated]) { 45 | // Not authenticated, don't even try refreshing 46 | return; 47 | }; 48 | 49 | [SVProgressHUD showWithStatus:@"Loading expenses..."]; 50 | 51 | PEExpensesViewController __weak *weakSelf = self; 52 | [[PKTItem fetchItemsInAppWithID:PODIO_APP_ID offset:0 limit:20] onSuccess:^(NSDictionary *result) { 53 | [SVProgressHUD dismiss]; 54 | 55 | PEExpensesViewController __strong *strongSelf = weakSelf; 56 | strongSelf.expenses = result[@"items"]; 57 | [strongSelf.tableView reloadData]; 58 | } onError:^(NSError *error) { 59 | [SVProgressHUD dismiss]; 60 | }]; 61 | } 62 | 63 | #pragma mark - UITableViewDataSource 64 | 65 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 66 | return [self.expenses count]; 67 | } 68 | 69 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 70 | static NSString * const identifier = @"ExpenseCell"; 71 | UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath]; 72 | 73 | PKTItem *expense = self.expenses[indexPath.row]; 74 | PKTMoney *money = expense[@"amount"]; 75 | NSString *amountString = [moneyFormatter stringFromNumber:money.amount]; 76 | 77 | cell.textLabel.text = expense.title; 78 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ %@", amountString, money.currency]; 79 | 80 | return cell; 81 | } 82 | 83 | #pragma mark - PEAddExpenseViewControllerDelegate 84 | 85 | - (void)addExpenseController:(PEAddExpenseViewController *)controller didAddExpense:(PKTItem *)expense { 86 | [self dismissViewControllerAnimated:YES completion:nil]; 87 | } 88 | 89 | #pragma mark - Storyboard 90 | 91 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 92 | // Make sure this VC is the delegate to be notified when a new expense is created in order 93 | // to dismiss the presented VC. 94 | if ([segue.identifier isEqualToString:@"AddExpense"]) { 95 | UINavigationController *navController = segue.destinationViewController; 96 | PEAddExpenseViewController *controller = (PEAddExpenseViewController *)navController.topViewController; 97 | controller.delegate = self; 98 | } 99 | } 100 | 101 | // This empty method is needed for the segue to be able to be unwinded. Don't ask me why. 102 | - (IBAction)closeAddExpense:(UIStoryboardSegue *)segue {} 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /PodioExpenses.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 502066C31922C384004721A1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 502066C21922C384004721A1 /* Foundation.framework */; }; 11 | 502066C51922C384004721A1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 502066C41922C384004721A1 /* CoreGraphics.framework */; }; 12 | 502066C71922C384004721A1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 502066C61922C384004721A1 /* UIKit.framework */; }; 13 | 502066CD1922C384004721A1 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 502066CB1922C384004721A1 /* InfoPlist.strings */; }; 14 | 502066CF1922C384004721A1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 502066CE1922C384004721A1 /* main.m */; }; 15 | 502066D31922C384004721A1 /* PEAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 502066D21922C384004721A1 /* PEAppDelegate.m */; }; 16 | 502066D61922C384004721A1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 502066D41922C384004721A1 /* Main.storyboard */; }; 17 | 502066DB1922C384004721A1 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 502066DA1922C384004721A1 /* Images.xcassets */; }; 18 | 502066F91923449E004721A1 /* PEExpensesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 502066F81923449E004721A1 /* PEExpensesViewController.m */; }; 19 | 502066FD19234942004721A1 /* PELoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 502066FC19234942004721A1 /* PELoginViewController.m */; }; 20 | 5020670A19239571004721A1 /* PEAddExpenseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020670919239571004721A1 /* PEAddExpenseViewController.m */; }; 21 | 86A431D5CEE64087AF44E78A /* libPods-PodioExpenses.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 463D34741DEE4A8AA9B648D3 /* libPods-PodioExpenses.a */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 463D34741DEE4A8AA9B648D3 /* libPods-PodioExpenses.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PodioExpenses.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 4D6BAD17B4DA4C12850AB88D /* Pods-PodioExpenses.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PodioExpenses.xcconfig"; path = "Pods/Pods-PodioExpenses.xcconfig"; sourceTree = ""; }; 27 | 502066BF1922C384004721A1 /* PodioExpenses.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PodioExpenses.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 502066C21922C384004721A1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 29 | 502066C41922C384004721A1 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 30 | 502066C61922C384004721A1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 31 | 502066CA1922C384004721A1 /* PodioExpenses-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PodioExpenses-Info.plist"; sourceTree = ""; }; 32 | 502066CC1922C384004721A1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 33 | 502066CE1922C384004721A1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | 502066D01922C384004721A1 /* PodioExpenses-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PodioExpenses-Prefix.pch"; sourceTree = ""; }; 35 | 502066D11922C384004721A1 /* PEAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEAppDelegate.h; sourceTree = ""; }; 36 | 502066D21922C384004721A1 /* PEAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEAppDelegate.m; sourceTree = ""; }; 37 | 502066D51922C384004721A1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 38 | 502066DA1922C384004721A1 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 39 | 502066E11922C384004721A1 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 40 | 502066F71923449E004721A1 /* PEExpensesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PEExpensesViewController.h; sourceTree = ""; }; 41 | 502066F81923449E004721A1 /* PEExpensesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PEExpensesViewController.m; sourceTree = ""; }; 42 | 502066FA19234677004721A1 /* PEConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEConfig.h; sourceTree = ""; }; 43 | 502066FB19234942004721A1 /* PELoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PELoginViewController.h; sourceTree = ""; }; 44 | 502066FC19234942004721A1 /* PELoginViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PELoginViewController.m; sourceTree = ""; }; 45 | 5020670819239571004721A1 /* PEAddExpenseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PEAddExpenseViewController.h; sourceTree = ""; }; 46 | 5020670919239571004721A1 /* PEAddExpenseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PEAddExpenseViewController.m; sourceTree = ""; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | 502066BC1922C384004721A1 /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | 502066C51922C384004721A1 /* CoreGraphics.framework in Frameworks */, 55 | 502066C71922C384004721A1 /* UIKit.framework in Frameworks */, 56 | 502066C31922C384004721A1 /* Foundation.framework in Frameworks */, 57 | 86A431D5CEE64087AF44E78A /* libPods-PodioExpenses.a in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 502066B61922C384004721A1 = { 65 | isa = PBXGroup; 66 | children = ( 67 | 502066C81922C384004721A1 /* PodioExpenses */, 68 | 502066C11922C384004721A1 /* Frameworks */, 69 | 502066C01922C384004721A1 /* Products */, 70 | 4D6BAD17B4DA4C12850AB88D /* Pods-PodioExpenses.xcconfig */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | 502066C01922C384004721A1 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 502066BF1922C384004721A1 /* PodioExpenses.app */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | 502066C11922C384004721A1 /* Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 502066C21922C384004721A1 /* Foundation.framework */, 86 | 502066C41922C384004721A1 /* CoreGraphics.framework */, 87 | 502066C61922C384004721A1 /* UIKit.framework */, 88 | 502066E11922C384004721A1 /* XCTest.framework */, 89 | 463D34741DEE4A8AA9B648D3 /* libPods-PodioExpenses.a */, 90 | ); 91 | name = Frameworks; 92 | sourceTree = ""; 93 | }; 94 | 502066C81922C384004721A1 /* PodioExpenses */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 502066FA19234677004721A1 /* PEConfig.h */, 98 | 502066D11922C384004721A1 /* PEAppDelegate.h */, 99 | 502066D21922C384004721A1 /* PEAppDelegate.m */, 100 | 502066FB19234942004721A1 /* PELoginViewController.h */, 101 | 502066FC19234942004721A1 /* PELoginViewController.m */, 102 | 502066F71923449E004721A1 /* PEExpensesViewController.h */, 103 | 502066F81923449E004721A1 /* PEExpensesViewController.m */, 104 | 5020670819239571004721A1 /* PEAddExpenseViewController.h */, 105 | 5020670919239571004721A1 /* PEAddExpenseViewController.m */, 106 | 502066D41922C384004721A1 /* Main.storyboard */, 107 | 502066DA1922C384004721A1 /* Images.xcassets */, 108 | 502066C91922C384004721A1 /* Supporting Files */, 109 | ); 110 | path = PodioExpenses; 111 | sourceTree = ""; 112 | }; 113 | 502066C91922C384004721A1 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 502066CA1922C384004721A1 /* PodioExpenses-Info.plist */, 117 | 502066CB1922C384004721A1 /* InfoPlist.strings */, 118 | 502066CE1922C384004721A1 /* main.m */, 119 | 502066D01922C384004721A1 /* PodioExpenses-Prefix.pch */, 120 | ); 121 | name = "Supporting Files"; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 502066BE1922C384004721A1 /* PodioExpenses */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 502066F11922C384004721A1 /* Build configuration list for PBXNativeTarget "PodioExpenses" */; 130 | buildPhases = ( 131 | 50C33B51CC474DBC940D719D /* Check Pods Manifest.lock */, 132 | 502066BB1922C384004721A1 /* Sources */, 133 | 502066BC1922C384004721A1 /* Frameworks */, 134 | 502066BD1922C384004721A1 /* Resources */, 135 | D06D99E7BE8F4A4AA961A38C /* Copy Pods Resources */, 136 | ); 137 | buildRules = ( 138 | ); 139 | dependencies = ( 140 | ); 141 | name = PodioExpenses; 142 | productName = PodioExpenses; 143 | productReference = 502066BF1922C384004721A1 /* PodioExpenses.app */; 144 | productType = "com.apple.product-type.application"; 145 | }; 146 | /* End PBXNativeTarget section */ 147 | 148 | /* Begin PBXProject section */ 149 | 502066B71922C384004721A1 /* Project object */ = { 150 | isa = PBXProject; 151 | attributes = { 152 | CLASSPREFIX = PE; 153 | LastUpgradeCheck = 0510; 154 | ORGANIZATIONNAME = "Citrix Systems, Inc."; 155 | }; 156 | buildConfigurationList = 502066BA1922C384004721A1 /* Build configuration list for PBXProject "PodioExpenses" */; 157 | compatibilityVersion = "Xcode 3.2"; 158 | developmentRegion = English; 159 | hasScannedForEncodings = 0; 160 | knownRegions = ( 161 | en, 162 | Base, 163 | ); 164 | mainGroup = 502066B61922C384004721A1; 165 | productRefGroup = 502066C01922C384004721A1 /* Products */; 166 | projectDirPath = ""; 167 | projectRoot = ""; 168 | targets = ( 169 | 502066BE1922C384004721A1 /* PodioExpenses */, 170 | ); 171 | }; 172 | /* End PBXProject section */ 173 | 174 | /* Begin PBXResourcesBuildPhase section */ 175 | 502066BD1922C384004721A1 /* Resources */ = { 176 | isa = PBXResourcesBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | 502066DB1922C384004721A1 /* Images.xcassets in Resources */, 180 | 502066CD1922C384004721A1 /* InfoPlist.strings in Resources */, 181 | 502066D61922C384004721A1 /* Main.storyboard in Resources */, 182 | ); 183 | runOnlyForDeploymentPostprocessing = 0; 184 | }; 185 | /* End PBXResourcesBuildPhase section */ 186 | 187 | /* Begin PBXShellScriptBuildPhase section */ 188 | 50C33B51CC474DBC940D719D /* Check Pods Manifest.lock */ = { 189 | isa = PBXShellScriptBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | ); 193 | inputPaths = ( 194 | ); 195 | name = "Check Pods Manifest.lock"; 196 | outputPaths = ( 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | shellPath = /bin/sh; 200 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 201 | showEnvVarsInLog = 0; 202 | }; 203 | D06D99E7BE8F4A4AA961A38C /* Copy Pods Resources */ = { 204 | isa = PBXShellScriptBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | ); 208 | inputPaths = ( 209 | ); 210 | name = "Copy Pods Resources"; 211 | outputPaths = ( 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | shellPath = /bin/sh; 215 | shellScript = "\"${SRCROOT}/Pods/Pods-PodioExpenses-resources.sh\"\n"; 216 | showEnvVarsInLog = 0; 217 | }; 218 | /* End PBXShellScriptBuildPhase section */ 219 | 220 | /* Begin PBXSourcesBuildPhase section */ 221 | 502066BB1922C384004721A1 /* Sources */ = { 222 | isa = PBXSourcesBuildPhase; 223 | buildActionMask = 2147483647; 224 | files = ( 225 | 502066CF1922C384004721A1 /* main.m in Sources */, 226 | 5020670A19239571004721A1 /* PEAddExpenseViewController.m in Sources */, 227 | 502066F91923449E004721A1 /* PEExpensesViewController.m in Sources */, 228 | 502066D31922C384004721A1 /* PEAppDelegate.m in Sources */, 229 | 502066FD19234942004721A1 /* PELoginViewController.m in Sources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXSourcesBuildPhase section */ 234 | 235 | /* Begin PBXVariantGroup section */ 236 | 502066CB1922C384004721A1 /* InfoPlist.strings */ = { 237 | isa = PBXVariantGroup; 238 | children = ( 239 | 502066CC1922C384004721A1 /* en */, 240 | ); 241 | name = InfoPlist.strings; 242 | sourceTree = ""; 243 | }; 244 | 502066D41922C384004721A1 /* Main.storyboard */ = { 245 | isa = PBXVariantGroup; 246 | children = ( 247 | 502066D51922C384004721A1 /* Base */, 248 | ); 249 | name = Main.storyboard; 250 | sourceTree = ""; 251 | }; 252 | /* End PBXVariantGroup section */ 253 | 254 | /* Begin XCBuildConfiguration section */ 255 | 502066EF1922C384004721A1 /* Debug */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 260 | CLANG_CXX_LIBRARY = "libc++"; 261 | CLANG_ENABLE_MODULES = YES; 262 | CLANG_ENABLE_OBJC_ARC = YES; 263 | CLANG_WARN_BOOL_CONVERSION = YES; 264 | CLANG_WARN_CONSTANT_CONVERSION = YES; 265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 266 | CLANG_WARN_EMPTY_BODY = YES; 267 | CLANG_WARN_ENUM_CONVERSION = YES; 268 | CLANG_WARN_INT_CONVERSION = YES; 269 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 271 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 272 | COPY_PHASE_STRIP = NO; 273 | GCC_C_LANGUAGE_STANDARD = gnu99; 274 | GCC_DYNAMIC_NO_PIC = NO; 275 | GCC_OPTIMIZATION_LEVEL = 0; 276 | GCC_PREPROCESSOR_DEFINITIONS = ( 277 | "DEBUG=1", 278 | "$(inherited)", 279 | ); 280 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 281 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 282 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 283 | GCC_WARN_UNDECLARED_SELECTOR = YES; 284 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 285 | GCC_WARN_UNUSED_FUNCTION = YES; 286 | GCC_WARN_UNUSED_VARIABLE = YES; 287 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 288 | ONLY_ACTIVE_ARCH = YES; 289 | SDKROOT = iphoneos; 290 | }; 291 | name = Debug; 292 | }; 293 | 502066F01922C384004721A1 /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ALWAYS_SEARCH_USER_PATHS = NO; 297 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 298 | CLANG_CXX_LIBRARY = "libc++"; 299 | CLANG_ENABLE_MODULES = YES; 300 | CLANG_ENABLE_OBJC_ARC = YES; 301 | CLANG_WARN_BOOL_CONVERSION = YES; 302 | CLANG_WARN_CONSTANT_CONVERSION = YES; 303 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 304 | CLANG_WARN_EMPTY_BODY = YES; 305 | CLANG_WARN_ENUM_CONVERSION = YES; 306 | CLANG_WARN_INT_CONVERSION = YES; 307 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 309 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 310 | COPY_PHASE_STRIP = YES; 311 | ENABLE_NS_ASSERTIONS = NO; 312 | GCC_C_LANGUAGE_STANDARD = gnu99; 313 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 314 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 315 | GCC_WARN_UNDECLARED_SELECTOR = YES; 316 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 317 | GCC_WARN_UNUSED_FUNCTION = YES; 318 | GCC_WARN_UNUSED_VARIABLE = YES; 319 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 320 | SDKROOT = iphoneos; 321 | VALIDATE_PRODUCT = YES; 322 | }; 323 | name = Release; 324 | }; 325 | 502066F21922C384004721A1 /* Debug */ = { 326 | isa = XCBuildConfiguration; 327 | baseConfigurationReference = 4D6BAD17B4DA4C12850AB88D /* Pods-PodioExpenses.xcconfig */; 328 | buildSettings = { 329 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 330 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 331 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 332 | GCC_PREFIX_HEADER = "PodioExpenses/PodioExpenses-Prefix.pch"; 333 | INFOPLIST_FILE = "PodioExpenses/PodioExpenses-Info.plist"; 334 | PRODUCT_NAME = "$(TARGET_NAME)"; 335 | WRAPPER_EXTENSION = app; 336 | }; 337 | name = Debug; 338 | }; 339 | 502066F31922C384004721A1 /* Release */ = { 340 | isa = XCBuildConfiguration; 341 | baseConfigurationReference = 4D6BAD17B4DA4C12850AB88D /* Pods-PodioExpenses.xcconfig */; 342 | buildSettings = { 343 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 344 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 345 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 346 | GCC_PREFIX_HEADER = "PodioExpenses/PodioExpenses-Prefix.pch"; 347 | INFOPLIST_FILE = "PodioExpenses/PodioExpenses-Info.plist"; 348 | PRODUCT_NAME = "$(TARGET_NAME)"; 349 | WRAPPER_EXTENSION = app; 350 | }; 351 | name = Release; 352 | }; 353 | /* End XCBuildConfiguration section */ 354 | 355 | /* Begin XCConfigurationList section */ 356 | 502066BA1922C384004721A1 /* Build configuration list for PBXProject "PodioExpenses" */ = { 357 | isa = XCConfigurationList; 358 | buildConfigurations = ( 359 | 502066EF1922C384004721A1 /* Debug */, 360 | 502066F01922C384004721A1 /* Release */, 361 | ); 362 | defaultConfigurationIsVisible = 0; 363 | defaultConfigurationName = Release; 364 | }; 365 | 502066F11922C384004721A1 /* Build configuration list for PBXNativeTarget "PodioExpenses" */ = { 366 | isa = XCConfigurationList; 367 | buildConfigurations = ( 368 | 502066F21922C384004721A1 /* Debug */, 369 | 502066F31922C384004721A1 /* Release */, 370 | ); 371 | defaultConfigurationIsVisible = 0; 372 | defaultConfigurationName = Release; 373 | }; 374 | /* End XCConfigurationList section */ 375 | }; 376 | rootObject = 502066B71922C384004721A1 /* Project object */; 377 | } 378 | -------------------------------------------------------------------------------- /PodioExpenses/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 97 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 191 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | --------------------------------------------------------------------------------