├── .gitignore
├── JenkinsCI.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── JenkinsCI.xcscheme
├── JenkinsCI.xcworkspace
└── contents.xcworkspacedata
├── JenkinsCI
├── Classes
│ ├── AppDelegate
│ │ ├── AppDelegate.h
│ │ └── AppDelegate.m
│ ├── Controllers
│ │ ├── ClubsViewController
│ │ │ ├── ClubsViewController.h
│ │ │ ├── ClubsViewController.m
│ │ │ └── Datasource
│ │ │ │ ├── ClubsViewController+UITableViewDatasource.h
│ │ │ │ └── ClubsViewController+UITableViewDatasource.m
│ │ ├── FetchedResultsTableViewController
│ │ │ ├── FetchedResultsTableViewController.h
│ │ │ └── FetchedResultsTableViewController.m
│ │ ├── PlayerProfileViewController
│ │ │ ├── PlayerProfileViewController.h
│ │ │ └── PlayerProfileViewController.m
│ │ ├── PlayersViewController
│ │ │ ├── Datasource
│ │ │ │ ├── PlayersViewController+UITableViewDatasource.h
│ │ │ │ └── PlayersViewController+UITableViewDatasource.m
│ │ │ ├── PlayersViewController.h
│ │ │ └── PlayersViewController.m
│ │ └── SquadViewController
│ │ │ ├── Datasource
│ │ │ ├── SquadViewController+TableViewDatasource.h
│ │ │ └── SquadViewController+TableViewDatasource.m
│ │ │ ├── SquadViewController.h
│ │ │ └── SquadViewController.m
│ ├── Managers
│ │ ├── CoreDataClubManager
│ │ │ ├── CoreDataClubManager.h
│ │ │ └── CoreDataClubManager.m
│ │ ├── CoreDataEntityManager
│ │ │ ├── CoreDataEntityManager.h
│ │ │ └── CoreDataEntityManager.m
│ │ ├── CoreDataManager
│ │ │ ├── CoreDataManager.h
│ │ │ └── CoreDataManager.m
│ │ ├── CoreDataPlayerManger
│ │ │ ├── CoreDataPlayerManager.h
│ │ │ └── CoreDataPlayerManager.m
│ │ └── DataImporter
│ │ │ ├── DataImporter.h
│ │ │ └── DataImporter.m
│ ├── Model
│ │ ├── Club
│ │ │ ├── Club.h
│ │ │ └── Club.m
│ │ └── Player
│ │ │ ├── Player.h
│ │ │ └── Player.m
│ ├── Utils
│ │ └── UIImageView+RoundCorners
│ │ │ ├── UIImageView+RoundCorners.h
│ │ │ └── UIImageView+RoundCorners.m
│ └── View
│ │ ├── ClubTableViewCell
│ │ ├── ClubTableViewCell.h
│ │ └── ClubTableViewCell.m
│ │ ├── PlayerTableViewCell
│ │ ├── PlayerTableViewCell.h
│ │ └── PlayerTableViewCell.m
│ │ └── SquadProfileTableViewCell
│ │ ├── SquadProfileTableViewCell.h
│ │ └── SquadProfileTableViewCell.m
├── CoreData
│ └── Model.xcdatamodeld
│ │ └── Model.xcdatamodel
│ │ └── contents
├── Info.plist
├── PrefixHeader.pch
├── Resources
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ └── Icon-Small@3x.png
│ │ ├── club-logos
│ │ │ ├── Arsenal-FC-logo.imageset
│ │ │ │ ├── Arsenal-FC-icon.png
│ │ │ │ └── Contents.json
│ │ │ ├── Chelsea-FC-logo.imageset
│ │ │ │ ├── Chelsea-FC-icon.png
│ │ │ │ └── Contents.json
│ │ │ ├── Everton-FC-logo.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── Everton-FC-icon.png
│ │ │ ├── Liverpool-FC-logo.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── Liverpool-FC-icon.png
│ │ │ └── Manchester-United-logo.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── Manchester-United-icon.png
│ │ ├── persons.imageset
│ │ │ ├── Contents.json
│ │ │ ├── persons@2x.png
│ │ │ └── persons@3x.png
│ │ ├── player-pictures
│ │ │ ├── aaron_ramsey.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── aaron_ramsey.png
│ │ │ ├── angel_di_maria.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── angel_di_maria.png
│ │ │ ├── daniel_sturridge.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── daniel_sturridge.png
│ │ │ ├── eden_hazard.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── eden_hazard.png
│ │ │ ├── jordan_henderson.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── jordan_henderson.png
│ │ │ ├── martin_skrtel.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── martin_skrtel.png
│ │ │ ├── player_placeholder.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── player_placeholder.png
│ │ │ ├── ross_barkley.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── ross_barkley.png
│ │ │ ├── steven_gerrard.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── steven_gerrard.png
│ │ │ └── wayne_rooney.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── wayne_rooney.png
│ │ └── stadium.imageset
│ │ │ ├── Contents.json
│ │ │ ├── stadium@2x.png
│ │ │ └── stadium@3x.png
│ └── db.json
└── main.m
├── JenkinsCITests
├── CoreDataTests
│ └── CoreDataImportTest.m
└── Info.plist
├── LICENSE
├── Podfile
├── Podfile.lock
├── Pods
├── CocoaLumberjack
│ ├── Classes
│ │ ├── CLI
│ │ │ ├── CLIColor.h
│ │ │ └── CLIColor.m
│ │ ├── CocoaLumberjack.h
│ │ ├── DDASLLogCapture.h
│ │ ├── DDASLLogCapture.m
│ │ ├── DDASLLogger.h
│ │ ├── DDASLLogger.m
│ │ ├── DDAbstractDatabaseLogger.h
│ │ ├── DDAbstractDatabaseLogger.m
│ │ ├── DDAssertMacros.h
│ │ ├── DDFileLogger.h
│ │ ├── DDFileLogger.m
│ │ ├── DDLog+LOGV.h
│ │ ├── DDLog.h
│ │ ├── DDLog.m
│ │ ├── DDLogMacros.h
│ │ ├── DDTTYLogger.h
│ │ ├── DDTTYLogger.m
│ │ └── Extensions
│ │ │ ├── DDContextFilterLogFormatter.h
│ │ │ ├── DDContextFilterLogFormatter.m
│ │ │ ├── DDDispatchQueueLogFormatter.h
│ │ │ ├── DDDispatchQueueLogFormatter.m
│ │ │ ├── DDMultiFormatter.h
│ │ │ └── DDMultiFormatter.m
│ ├── LICENSE.txt
│ └── README.md
├── CrashlyticsFramework
│ ├── Crashlytics.framework
│ │ ├── Crashlytics
│ │ ├── Headers
│ │ ├── Modules
│ │ │ └── module.modulemap
│ │ ├── Resources
│ │ ├── Versions
│ │ │ ├── A
│ │ │ │ ├── Crashlytics
│ │ │ │ ├── Headers
│ │ │ │ │ └── Crashlytics.h
│ │ │ │ └── Resources
│ │ │ │ │ └── Info.plist
│ │ │ └── Current
│ │ ├── run
│ │ └── submit
│ ├── LICENSE
│ └── README.md
├── Headers
│ └── Public
│ │ ├── CocoaLumberjack
│ │ ├── CLIColor.h
│ │ ├── CocoaLumberjack.h
│ │ ├── DDASLLogCapture.h
│ │ ├── DDASLLogger.h
│ │ ├── DDAbstractDatabaseLogger.h
│ │ ├── DDAssertMacros.h
│ │ ├── DDContextFilterLogFormatter.h
│ │ ├── DDDispatchQueueLogFormatter.h
│ │ ├── DDFileLogger.h
│ │ ├── DDLog+LOGV.h
│ │ ├── DDLog.h
│ │ ├── DDLogMacros.h
│ │ ├── DDMultiFormatter.h
│ │ └── DDTTYLogger.h
│ │ └── CrashlyticsFramework
│ │ └── Crashlytics.h
├── Manifest.lock
├── Pods.xcodeproj
│ └── project.pbxproj
└── Target Support Files
│ ├── Pods-CocoaLumberjack
│ ├── Pods-CocoaLumberjack-Private.xcconfig
│ ├── Pods-CocoaLumberjack-dummy.m
│ ├── Pods-CocoaLumberjack-prefix.pch
│ └── Pods-CocoaLumberjack.xcconfig
│ ├── Pods-CrashlyticsFramework
│ ├── Pods-CrashlyticsFramework-Private.xcconfig
│ ├── Pods-CrashlyticsFramework-dummy.m
│ ├── Pods-CrashlyticsFramework-prefix.pch
│ └── Pods-CrashlyticsFramework.xcconfig
│ └── Pods
│ ├── Pods-acknowledgements.markdown
│ ├── Pods-acknowledgements.plist
│ ├── Pods-dummy.m
│ ├── Pods-environment.h
│ ├── Pods-resources.sh
│ ├── Pods.debug.xcconfig
│ └── Pods.release.xcconfig
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | # Pods/
27 |
--------------------------------------------------------------------------------
/JenkinsCI.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/JenkinsCI.xcodeproj/xcshareddata/xcschemes/JenkinsCI.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
69 |
70 |
79 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
98 |
104 |
105 |
106 |
107 |
109 |
110 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/JenkinsCI.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/AppDelegate/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/AppDelegate/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DataImporter.h"
11 | #import
12 |
13 | @interface AppDelegate ()
14 |
15 | @end
16 |
17 | @implementation AppDelegate
18 |
19 |
20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
21 | // Override point for customization after application launch.
22 |
23 | // Checks if the import has been done and if not imports the data
24 | [self checkImport];
25 |
26 | // Start Crashlytics
27 | [self startCrashlytics];
28 |
29 | return YES;
30 | }
31 |
32 | - (void)applicationWillResignActive:(UIApplication *)application {
33 | // 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.
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidEnterBackground:(UIApplication *)application {
38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
40 | }
41 |
42 | - (void)applicationWillEnterForeground:(UIApplication *)application {
43 | // 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.
44 | }
45 |
46 | - (void)applicationDidBecomeActive:(UIApplication *)application {
47 | // 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.
48 | }
49 |
50 | - (void)applicationWillTerminate:(UIApplication *)application {
51 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
52 | }
53 |
54 | #pragma mark - Import
55 |
56 | - (void)checkImport {
57 | DataImporter *importer = [[DataImporter alloc] init];
58 | if (![importer didImportData]) {
59 | [importer importData];
60 | }
61 | }
62 |
63 |
64 |
65 | #pragma mark - Crashlytics
66 |
67 | - (void)startCrashlytics {
68 | // [Crashlytics startWithAPIKey:<#(NSString *)#>];
69 | //#ifdef DEBUG
70 | // [[Crashlytics sharedInstance] setDebugMode:YES];
71 | //#else
72 | // [[Crashlytics sharedInstance] setDebugMode:NO];
73 | //#endif
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/ClubsViewController/ClubsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ClubsViewController.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreDataManager.h"
11 | #import "FetchedResultsTableViewController.h"
12 |
13 | @interface ClubsViewController : FetchedResultsTableViewController
14 |
15 | @property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/ClubsViewController/ClubsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ClubsViewController.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "ClubsViewController.h"
10 | #import "SquadViewController.h"
11 | #import "ClubsViewController+UITableViewDatasource.h"
12 |
13 | static NSString * const kClubFetchEntityName = @"Club";
14 | static NSString * const kClubFetchSortingKey = @"clubName";
15 |
16 | static NSString * const kPresentSquadSegueIdentifier = @"segue_clubsShowSquad";
17 |
18 | @interface ClubsViewController ()
19 |
20 | @end
21 |
22 | @implementation ClubsViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 |
27 | // Uncomment the following line to preserve selection between presentations.
28 | // self.clearsSelectionOnViewWillAppear = NO;
29 |
30 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
31 | // self.navigationItem.rightBarButtonItem = self.editButtonItem;
32 |
33 | [self setupClubsFetchedResultsControler];
34 | }
35 |
36 | - (void)didReceiveMemoryWarning {
37 | [super didReceiveMemoryWarning];
38 | // Dispose of any resources that can be recreated.
39 | }
40 |
41 | - (void)setupClubsFetchedResultsControler {
42 | CoreDataManager *manager = [CoreDataManager sharedInstance];
43 | self.fetchedResultsController = [manager fetchedResultsControllerWithEntityName:kClubFetchEntityName
44 | predicate:nil
45 | sortingKeys:@[kClubFetchSortingKey]
46 | sectionNameKey:nil
47 | ascending:YES
48 | delegate:self];
49 |
50 | self.cellConfigurer = self;
51 |
52 | NSError *error = nil;
53 | [self.fetchedResultsController performFetch:&error];
54 | if (error) {
55 | DDLogError(@"Fetch Erorr: %@", error);
56 | }
57 |
58 | }
59 |
60 |
61 | #pragma mark - Navigation
62 |
63 | - (void)prepareForSegue:(UIStoryboardSegue *)segue
64 | sender:(id)sender
65 | {
66 | if ([segue.identifier isEqualToString:kPresentSquadSegueIdentifier]) {
67 | SquadViewController *squadViewController = (SquadViewController *)segue.destinationViewController;
68 | squadViewController.presentedClub = [self.fetchedResultsController objectAtIndexPath:self.tableView.indexPathForSelectedRow];
69 | }
70 | }
71 |
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/ClubsViewController/Datasource/ClubsViewController+UITableViewDatasource.h:
--------------------------------------------------------------------------------
1 | //
2 | // ClubsViewController+UITableViewDatasource.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "ClubsViewController.h"
10 |
11 | @interface ClubsViewController (UITableViewDatasource)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/ClubsViewController/Datasource/ClubsViewController+UITableViewDatasource.m:
--------------------------------------------------------------------------------
1 | //
2 | // ClubsViewController+UITableViewDatasource.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "ClubsViewController+UITableViewDatasource.h"
10 | #import "ClubTableViewCell.h"
11 | #import "Club.h"
12 |
13 | static NSString * const kClubsCellIdentifier = @"_clubCell";
14 |
15 | @implementation ClubsViewController (UITableViewDatasource)
16 |
17 |
18 | #pragma mark - UITableViewDataSource
19 |
20 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
21 | return 1;
22 | }
23 |
24 | - (NSInteger)tableView:(UITableView *)tableView
25 | numberOfRowsInSection:(NSInteger)section
26 | {
27 | return [[self.fetchedResultsController fetchedObjects] count];
28 | }
29 |
30 | - (UITableViewCell *)tableView:(UITableView *)tableView
31 | cellForRowAtIndexPath:(NSIndexPath *)indexPath
32 | {
33 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kClubsCellIdentifier
34 | forIndexPath:indexPath];
35 |
36 | [self configureCell:cell forRowAtIndexPath:indexPath];
37 |
38 | return cell;
39 | }
40 |
41 | - (void)configureCell:(UITableViewCell *)cell
42 | forRowAtIndexPath:(NSIndexPath *)indexPath
43 | {
44 | Club *club = [self.fetchedResultsController objectAtIndexPath:indexPath];
45 | ClubTableViewCell *clubCell = (ClubTableViewCell *)cell;
46 |
47 | clubCell.clubNameLabel.text = club.clubName;
48 | clubCell.clubLogoView.image = [club logoImage];
49 | clubCell.squadSizeLabel.text = [self squadSizeForClub:club];
50 |
51 | }
52 |
53 |
54 | - (NSString *)squadSizeForClub:(Club *)club {
55 | NSInteger size = [club.squad count];
56 | NSString *squadSize;
57 | switch (size) {
58 | case 0:
59 | squadSize = @"No players";
60 | break;
61 | case 1:
62 | squadSize = @"One player";
63 | break;
64 | default:
65 | squadSize = [NSString stringWithFormat:@"%li players", (long)size];
66 | break;
67 | }
68 |
69 | return squadSize;
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/FetchedResultsTableViewController/FetchedResultsTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // FetchedResultsTableViewController.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 24/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | @import CoreData;
11 |
12 | @protocol UITableViewCellConfigurer
13 |
14 | - (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
15 |
16 | @end
17 |
18 | @interface FetchedResultsTableViewController : UITableViewController
19 |
20 | /**
21 | * Cell configurerDelegate object.
22 | */
23 | @property (nonatomic, assign) id cellConfigurer;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/FetchedResultsTableViewController/FetchedResultsTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // FetchedResultsTableViewController.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 24/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "FetchedResultsTableViewController.h"
10 |
11 |
12 | @implementation FetchedResultsTableViewController
13 |
14 | #pragma mark - NSFetchedResultsControllerDelegate
15 |
16 | - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
17 | [self.tableView beginUpdates];
18 | }
19 |
20 | - (void)controller:(NSFetchedResultsController *)controller
21 | didChangeSection:(id )sectionInfo
22 | atIndex:(NSUInteger)sectionIndex
23 | forChangeType:(NSFetchedResultsChangeType)type
24 | {
25 | switch(type) {
26 | case NSFetchedResultsChangeInsert:
27 | [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
28 | break;
29 | case NSFetchedResultsChangeDelete:
30 | [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
31 | break;
32 | default:
33 | break;
34 | }
35 | }
36 |
37 | - (void)controller:(NSFetchedResultsController *)controller
38 | didChangeObject:(id)object
39 | atIndexPath:(NSIndexPath *)indexPath
40 | forChangeType:(NSFetchedResultsChangeType)type
41 | newIndexPath:(NSIndexPath *)newIndexPath
42 | {
43 | switch(type) {
44 | case NSFetchedResultsChangeInsert:
45 | [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
46 | break;
47 | case NSFetchedResultsChangeDelete:
48 | [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
49 | break;
50 | case NSFetchedResultsChangeUpdate:
51 | [self.cellConfigurer configureCell:[self.tableView cellForRowAtIndexPath:indexPath] forRowAtIndexPath:indexPath];
52 | break;
53 | case NSFetchedResultsChangeMove:
54 | [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
55 | [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
56 | break;
57 | }
58 | }
59 |
60 | - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
61 | [self.tableView endUpdates];
62 | }
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayerProfileViewController/PlayerProfileViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayerProfileViewController.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class Player;
12 |
13 | @interface PlayerProfileViewController : UIViewController
14 |
15 | @property (nonatomic, strong) Player *presentedPlayer;
16 |
17 | // Interface outlets
18 | @property (weak, nonatomic) IBOutlet UILabel *playerNumberLabel;
19 | @property (weak, nonatomic) IBOutlet UIImageView *playerAvatarImageView;
20 | @property (weak, nonatomic) IBOutlet UILabel *playerFirstNameLabel;
21 | @property (weak, nonatomic) IBOutlet UILabel *playerLastNameLabel;
22 | @property (weak, nonatomic) IBOutlet UILabel *clubNameLabel;
23 | @property (weak, nonatomic) IBOutlet UIImageView *clubLogoImageView;
24 | @property (weak, nonatomic) IBOutlet UILabel *playerPositionLabel;
25 |
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayerProfileViewController/PlayerProfileViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayerProfileViewController.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "PlayerProfileViewController.h"
10 | #import "Player.h"
11 | #import "Club.h"
12 |
13 | @interface PlayerProfileViewController ()
14 |
15 | @end
16 |
17 | @implementation PlayerProfileViewController
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 | // Do any additional setup after loading the view.
22 | }
23 |
24 | - (void)didReceiveMemoryWarning {
25 | [super didReceiveMemoryWarning];
26 | // Dispose of any resources that can be recreated.
27 | }
28 |
29 | - (void)viewWillAppear:(BOOL)animated {
30 | [super viewWillAppear:animated];
31 | self.title = [self.presentedPlayer playerFullName];
32 | [self setupPlayerView];
33 | }
34 |
35 | - (void)setupPlayerView {
36 | self.playerFirstNameLabel.text = self.presentedPlayer.firstName;
37 | self.playerLastNameLabel.text = self.presentedPlayer.lastName;
38 | self.playerAvatarImageView.image = [self.presentedPlayer playerImage];
39 | self.playerPositionLabel.text = self.presentedPlayer.position;
40 | self.clubNameLabel.text = self.presentedPlayer.club.clubName;
41 | self.clubLogoImageView.image = [self.presentedPlayer.club logoImage];
42 | self.playerNumberLabel.text = [NSString stringWithFormat:@"No. %@", self.presentedPlayer.shirtNumber];
43 | }
44 |
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayersViewController/Datasource/PlayersViewController+UITableViewDatasource.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayersViewController+UITableViewDatasource.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "PlayersViewController.h"
10 |
11 | @interface PlayersViewController (UITableViewDatasource)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayersViewController/Datasource/PlayersViewController+UITableViewDatasource.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayersViewController+UITableViewDatasource.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "PlayersViewController+UITableViewDatasource.h"
10 | #import "PlayerTableViewCell.h"
11 | #import "Player.h"
12 | #import "Club.h"
13 |
14 | static NSString * const kPlayerCellIdentifier = @"_playerCell";
15 |
16 | @implementation PlayersViewController (UITableViewDatasource)
17 |
18 |
19 | #pragma mark - UITableViewDataSource
20 |
21 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
22 | return 1;
23 | }
24 |
25 | - (NSInteger)tableView:(UITableView *)tableView
26 | numberOfRowsInSection:(NSInteger)section
27 | {
28 | return [[self.fetchedResultsController fetchedObjects] count];
29 | }
30 |
31 | - (UITableViewCell *)tableView:(UITableView *)tableView
32 | cellForRowAtIndexPath:(NSIndexPath *)indexPath
33 | {
34 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kPlayerCellIdentifier
35 | forIndexPath:indexPath];
36 |
37 | [self configureCell:cell forRowAtIndexPath:indexPath];
38 |
39 | return cell;
40 | }
41 |
42 | - (void)configureCell:(UITableViewCell *)cell
43 | forRowAtIndexPath:(NSIndexPath *)indexPath
44 | {
45 | Player *player = [self.fetchedResultsController objectAtIndexPath:indexPath];
46 | PlayerTableViewCell *playerCell = (PlayerTableViewCell *)cell;
47 |
48 | playerCell.playerFullNameLabel.text = [player playerFullName];
49 | playerCell.playerImageView.image = [player playerImage];
50 | playerCell.playerPositionLabel.text = player.position;
51 | playerCell.clubNameLabel.text = player.club.clubName;
52 | }
53 |
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayersViewController/PlayersViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayersViewController.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreDataManager.h"
11 | #import "FetchedResultsTableViewController.h"
12 |
13 | @interface PlayersViewController : FetchedResultsTableViewController
14 |
15 | @property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/PlayersViewController/PlayersViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayersViewController.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "PlayersViewController.h"
10 | #import "PlayerProfileViewController.h"
11 | #import "PlayersViewController+UITableViewDatasource.h"
12 | #import "Player.h"
13 |
14 |
15 | static NSString * const kPlayerFetchEntityName = @"Player";
16 | static NSString * const kPlayerFetchSortingKeyLast = @"lastName";
17 | static NSString * const kPlayerFetchSortingKeyFirst = @"firstName";
18 |
19 | static NSString * const kPresentPlayerSegue = @"segue_playersShowPlayer";
20 |
21 | @interface PlayersViewController ()
22 |
23 | @end
24 |
25 | @implementation PlayersViewController
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 |
30 | // Uncomment the following line to preserve selection between presentations.
31 | // self.clearsSelectionOnViewWillAppear = NO;
32 |
33 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
34 | // self.navigationItem.rightBarButtonItem = self.editButtonItem;
35 |
36 | [self setupPlayersFetchedResultsController];
37 | }
38 |
39 | - (void)didReceiveMemoryWarning {
40 | [super didReceiveMemoryWarning];
41 | // Dispose of any resources that can be recreated.
42 | }
43 |
44 |
45 | - (void)setupPlayersFetchedResultsController {
46 | CoreDataManager *manager = [CoreDataManager sharedInstance];
47 | NSArray *sortingKeys = @[kPlayerFetchSortingKeyLast, kPlayerFetchSortingKeyFirst];
48 | self.fetchedResultsController = [manager fetchedResultsControllerWithEntityName:kPlayerFetchEntityName
49 | predicate:nil
50 | sortingKeys:sortingKeys
51 | sectionNameKey:nil
52 | ascending:YES
53 | delegate:self];
54 |
55 | self.cellConfigurer = self;
56 |
57 | NSError *error = nil;
58 | [self.fetchedResultsController performFetch:&error];
59 | if (error) {
60 | DDLogError(@"Fetch Erorr: %@", error);
61 | }
62 | }
63 |
64 |
65 | #pragma mark - Navigation
66 |
67 | - (void)prepareForSegue:(UIStoryboardSegue *)segue
68 | sender:(id)sender
69 | {
70 | if ([[segue identifier] isEqualToString:kPresentPlayerSegue]) {
71 | PlayerProfileViewController *playerViewController = (PlayerProfileViewController *)segue.destinationViewController;
72 | Player *player = [self.fetchedResultsController objectAtIndexPath:self.tableView.indexPathForSelectedRow];
73 | [playerViewController setPresentedPlayer:player];
74 | }
75 | }
76 |
77 |
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/SquadViewController/Datasource/SquadViewController+TableViewDatasource.h:
--------------------------------------------------------------------------------
1 | //
2 | // SquadViewController+TableViewDatasource.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "SquadViewController.h"
10 |
11 | @interface SquadViewController (TableViewDatasource)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/SquadViewController/Datasource/SquadViewController+TableViewDatasource.m:
--------------------------------------------------------------------------------
1 | //
2 | // SquadViewController+TableViewDatasource.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "SquadViewController+TableViewDatasource.h"
10 | #import "SquadProfileTableViewCell.h"
11 | #import "Player.h"
12 |
13 | static NSString * const kSquadCellIdentifier = @"_squadProfileCell";
14 |
15 | @implementation SquadViewController (TableViewDatasource)
16 |
17 |
18 | #pragma mark - UITableViewDataSource
19 |
20 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
21 | return 1;
22 | }
23 |
24 | - (NSInteger)tableView:(UITableView *)tableView
25 | numberOfRowsInSection:(NSInteger)section
26 | {
27 | return [[self.fetchedResultsController fetchedObjects] count];
28 | }
29 |
30 | - (UITableViewCell *)tableView:(UITableView *)tableView
31 | cellForRowAtIndexPath:(NSIndexPath *)indexPath
32 | {
33 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kSquadCellIdentifier
34 | forIndexPath:indexPath];
35 |
36 | [self configureCell:cell forRowAtIndexPath:indexPath];
37 |
38 | return cell;
39 | }
40 |
41 | - (void)configureCell:(UITableViewCell *)cell
42 | forRowAtIndexPath:(NSIndexPath *)indexPath
43 | {
44 | SquadProfileTableViewCell *playerCell = (SquadProfileTableViewCell *)cell;
45 | Player *player = [self.fetchedResultsController objectAtIndexPath:indexPath];
46 | playerCell.playerFullNameLabel.text = [player playerFullName];
47 | playerCell.playerNumberLabel.text = [player.shirtNumber stringValue];
48 | playerCell.playerPictureView.image = [player playerImage];
49 | playerCell.playerPositionLabel.text = player.position;
50 | }
51 |
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/SquadViewController/SquadViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SquadViewController.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CoreDataManager.h"
11 | #import "FetchedResultsTableViewController.h"
12 | @class Club;
13 |
14 | @interface SquadViewController : FetchedResultsTableViewController
15 |
16 | @property (nonatomic, strong) Club *presentedClub;
17 | @property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Controllers/SquadViewController/SquadViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SquadViewController.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "SquadViewController.h"
10 | #import "PlayerProfileViewController.h"
11 | #import "SquadViewController+TableViewDatasource.h"
12 | #import "Club.h"
13 |
14 | static NSString * const kSquadPresentPlayerSegue = @"segue_squadShowPlayer";
15 |
16 | @interface SquadViewController ()
17 |
18 | @end
19 |
20 | @implementation SquadViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 |
25 | // Uncomment the following line to preserve selection between presentations.
26 | // self.clearsSelectionOnViewWillAppear = NO;
27 |
28 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
29 | // self.navigationItem.rightBarButtonItem = self.editButtonItem;
30 | }
31 |
32 | - (void)didReceiveMemoryWarning {
33 | [super didReceiveMemoryWarning];
34 | // Dispose of any resources that can be recreated.
35 | }
36 |
37 | - (void)viewWillAppear:(BOOL)animated {
38 | [super viewWillAppear:animated];
39 | [self prepareFetchedResultsController];
40 |
41 | self.title = self.presentedClub.clubName;
42 | }
43 |
44 |
45 | #pragma mark - NSFetchedResultsController
46 |
47 | - (void)prepareFetchedResultsController {
48 | CoreDataManager *manager = [CoreDataManager sharedInstance];
49 |
50 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"club.clubId == %@", self.presentedClub.clubId];
51 | NSArray *sortingKeys = @[@"position", @"lastName", @"firstName"];
52 |
53 | self.fetchedResultsController = [manager fetchedResultsControllerWithEntityName:@"Player"
54 | predicate:predicate
55 | sortingKeys:sortingKeys
56 | sectionNameKey:nil
57 | ascending:YES
58 | delegate:self];
59 | self.cellConfigurer = self;
60 | NSError *error = nil;
61 | [self.fetchedResultsController performFetch:&error];
62 | if (error) {
63 | DDLogError(@"Fetch Erorr: %@", error);
64 | }
65 |
66 | }
67 |
68 | #pragma mark - Navigation
69 |
70 | - (void)prepareForSegue:(UIStoryboardSegue *)segue
71 | sender:(id)sender
72 | {
73 | if ([[segue identifier] isEqualToString:kSquadPresentPlayerSegue]) {
74 | PlayerProfileViewController *playerViewController = (PlayerProfileViewController *)segue.destinationViewController;
75 | Player *player = [self.fetchedResultsController objectAtIndexPath:self.tableView.indexPathForSelectedRow];
76 | [playerViewController setPresentedPlayer:player];
77 | }
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataClubManager/CoreDataClubManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataClubManager.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEntityManager.h"
10 | #import "Club.h"
11 |
12 | @interface CoreDataClubManager : CoreDataEntityManager
13 |
14 | /**
15 | * Method that creates a Club with a given name and stadium name.
16 | *
17 | * @param clubName The club name.
18 | * @param clubId The club id.
19 | *
20 | * @return Club instance.
21 | */
22 | - (Club *)createClubWithName:(NSString *)clubName
23 | clubId:(NSNumber *)clubId;
24 |
25 | /**
26 | * Deletes a club from its managed object context.
27 | *
28 | * @param club Club object.
29 | */
30 | - (void)deleteClub:(Club *)club;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataClubManager/CoreDataClubManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataClubManager.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "CoreDataClubManager.h"
10 | #import "CoreDataManager.h"
11 |
12 | @implementation CoreDataClubManager
13 |
14 | - (Club *)createClubWithName:(NSString *)clubName
15 | clubId:(NSNumber *)clubId
16 | {
17 | // Get the club class name
18 | NSString *clubClassName = NSStringFromClass([Club class]);
19 | // Get the main context
20 | NSManagedObjectContext *context = [[CoreDataManager sharedInstance] mainManagedObjectContext];
21 | // Create the entity
22 | Club *clubObject = (Club *)[self createNSManagedObjectWithEntityName:clubClassName
23 | onContext:context];
24 | // Set it's properties
25 | clubObject.clubName = clubName;
26 | clubObject.clubId = clubId;
27 |
28 | return clubObject;
29 | }
30 |
31 | - (void)deleteClub:(Club *)club {
32 | [self deleteObject:club];
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataEntityManager/CoreDataEntityManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEntityManager.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | @import CoreData;
11 |
12 | /**
13 | * Base class for CoreData manager classes.
14 | */
15 | @interface CoreDataEntityManager : NSObject
16 |
17 | /**
18 | * The NSManagedObjectContext on which the CoreDataEntityManager instace will operate on.
19 | */
20 | @property (nonatomic, strong, readonly) NSManagedObjectContext *managedObjectContext;
21 |
22 | /**
23 | * Designated initializer.
24 | *
25 | * @param context Instantiates a CoreDataEntityManager with a given context.
26 | *
27 | * @return CoreDataEntityManager instance.
28 | */
29 | - (instancetype)initWithContext:(NSManagedObjectContext *)context;
30 |
31 | /**
32 | * Creates a NSManagedObject with a given entity name on the passed NSManagedObjectContext.
33 | *
34 | * @param entityName NSString representing a valid entity name.
35 | * @param context The NSManagedObjectContext on which the object will be created.
36 | *
37 | * @return NSManagedObject instance or nil.
38 | */
39 | - (NSManagedObject *)createNSManagedObjectWithEntityName:(NSString *)entityName
40 | onContext:(NSManagedObjectContext *)context;
41 |
42 | /**
43 | * Deletes an object from its managed object context.
44 | *
45 | * @param object The NSManagedObject instance to be deleted;
46 | */
47 | - (void)deleteObject:(NSManagedObject *)object;
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataEntityManager/CoreDataEntityManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataEntityManager.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEntityManager.h"
10 |
11 | @implementation CoreDataEntityManager
12 |
13 | - (instancetype)initWithContext:(NSManagedObjectContext *)context {
14 |
15 | NSAssert((context != nil && [context isKindOfClass:[NSManagedObjectContext class]]),
16 | @"The NSManagedObjectContext must not be nil or of any other type.");
17 |
18 | if (self = [super init]) {
19 | // Set the managed object context
20 | _managedObjectContext = context;
21 | }
22 |
23 | return self;
24 | }
25 |
26 | - (NSManagedObject *)createNSManagedObjectWithEntityName:(NSString *)entityName
27 | onContext:(NSManagedObjectContext *)context
28 | {
29 | return [NSEntityDescription insertNewObjectForEntityForName:entityName
30 | inManagedObjectContext:context];
31 | }
32 |
33 | - (void)deleteObject:(NSManagedObject *)object {
34 | NSManagedObjectContext *context = object.managedObjectContext;
35 | [context deleteObject:object];
36 | object = nil;
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataManager/CoreDataManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataManager.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/07/14.
6 | // Copyright (c) 2014 Endava. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | /**
13 | * Singleton class that manages the CoreData stack.
14 | */
15 | @interface CoreDataManager : NSObject
16 |
17 | /**
18 | * The main queue priority NSManagedObjectContext instance.
19 | */
20 | @property (nonatomic, strong, readonly) NSManagedObjectContext *mainManagedObjectContext;
21 |
22 | /**
23 | * Returns a pointer to the singleton class instance.
24 | *
25 | * @return CoreDataManager instance.
26 | */
27 | + (instancetype)sharedInstance;
28 |
29 | /**
30 | * Saves the main queue priority context.
31 | */
32 | - (void)saveContext;
33 |
34 | /**
35 | * Performs a fetch request on the main queue managed object context with a set of
36 | * required parameters.
37 | *
38 | * @param entityName NSString instance representing a CoreData entity name.
39 | * @param predicate NSPredicate instance describing the fetch rule.
40 | * @param sortingKeys Array containing NSString instances representing the entity
41 | * property by which the sorting will be done.
42 | * @param ascending YES - Ascending.
43 | *
44 | * @return NSArray of NSManagedObject instances of that entityName type.
45 | */
46 | - (NSArray *)fetchObjectsWithEntityName:(NSString *)entityName
47 | predicate:(NSPredicate *)predicate
48 | sortingKeys:(NSArray *)sortingKeys
49 | ascending:(BOOL)ascending;
50 |
51 |
52 | /**
53 | * Creates a NSFetchedResultsController with a set of parameters.
54 | *
55 | * @param entityName The entity name to fetch.
56 | * @param predicate The NSPredicate instance for the search.
57 | * @param sortingKeys The fetch sorting keys.
58 | * @param sectionNameKey The section name key.
59 | * @param ascending YES - ascending.
60 | * @param delegate The delegate for the search.
61 | *
62 | * @return NSFetchedResultsController instance.
63 | */
64 | - (NSFetchedResultsController *)fetchedResultsControllerWithEntityName:(NSString *)entityName
65 | predicate:(NSPredicate *)predicate
66 | sortingKeys:(NSArray *)sortingKeys
67 | sectionNameKey:(NSString *)sectionKey
68 | ascending:(BOOL)ascending
69 | delegate:(id)delegate;
70 |
71 | /**
72 | * Returns a newly instantiated NSManagedObjectContext with a private queue priority.
73 | *
74 | * @return NSManagedObjectContext instance.
75 | */
76 | @property (nonatomic, strong, readonly) NSManagedObjectContext *backgroundQueueManagedObjectContext;
77 |
78 | @end
79 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataManager/CoreDataManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataManager.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/07/14.
6 | // Copyright (c) 2014 Endava. All rights reserved.
7 | //
8 |
9 | #import "CoreDataManager.h"
10 |
11 | @interface CoreDataManager ()
12 |
13 | @property (nonatomic, strong, readonly) NSManagedObjectModel *managedObjectModel;
14 | @property (nonatomic, strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
15 |
16 | - (NSURL *)applicationDocumentsDirectory;
17 |
18 | @end
19 |
20 | @implementation CoreDataManager
21 |
22 | @synthesize mainManagedObjectContext = _mainManagedObjectContext;
23 | @synthesize managedObjectModel = _managedObjectModel;
24 | @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
25 |
26 | #pragma mark - Initialization
27 |
28 | + (instancetype)sharedInstance {
29 | static dispatch_once_t onceToken;
30 | __strong static id _sharedObject = nil;
31 | dispatch_once(&onceToken, ^{
32 | _sharedObject = [[self alloc] init];
33 | });
34 |
35 | return _sharedObject;
36 | }
37 |
38 |
39 | #pragma mark - CoreData Operations
40 | - (void)saveContext {
41 | NSError *error = nil;
42 | NSManagedObjectContext *managedObjectContext = self.mainManagedObjectContext;
43 | if (managedObjectContext != nil) {
44 | if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
45 |
46 | DDLogWarn(@"Unresolved error main context %@, %@", error, [error userInfo]);
47 |
48 | NSArray * conflictListArray = (NSArray*)[[error userInfo] objectForKey:@"conflictList"];
49 | DDLogWarn(@"conflict array: %@",conflictListArray);
50 | NSError * conflictFixError = nil;
51 |
52 | if ([conflictListArray count] > 0) {
53 |
54 | NSMergePolicy *mergePolicy = [[NSMergePolicy alloc] initWithMergeType:NSOverwriteMergePolicyType];
55 |
56 | if (![mergePolicy resolveConflicts:conflictListArray error:&conflictFixError]) {
57 | DDLogError(@"Unresolved conflict error %@, %@", conflictFixError, [conflictFixError userInfo]);
58 | DDLogError(@"abort");
59 | abort();
60 | }
61 | }
62 | }
63 | }
64 | if (error) {
65 | DDLogError(@"Unresolved conflict error %@", [error userInfo]);
66 | }
67 | }
68 |
69 | - (NSArray *)fetchObjectsWithEntityName:(NSString *)entityName
70 | predicate:(NSPredicate *)predicate
71 | sortingKeys:(NSArray *)sortingKeys
72 | ascending:(BOOL)ascending
73 | {
74 |
75 | // Create a fetch request with a specific entity
76 | NSFetchRequest *fetchRequest = [self fetchRequestWithEntityName:entityName
77 | predicate:predicate
78 | sortingKeys:sortingKeys
79 | ascending:ascending];
80 | NSError *error = nil;
81 | NSArray *fetchedObjects = [self.mainManagedObjectContext executeFetchRequest:fetchRequest error:&error];
82 | if (error) {
83 | DDLogError(@"Fetch Error: %@", [error description]);
84 | }
85 |
86 | return fetchedObjects;
87 | }
88 |
89 | - (NSFetchedResultsController *)fetchedResultsControllerWithEntityName:(NSString *)entityName
90 | predicate:(NSPredicate *)predicate
91 | sortingKeys:(NSArray *)sortingKeys
92 | sectionNameKey:(NSString *)sectionKey
93 | ascending:(BOOL)ascending
94 | delegate:(id)delegate
95 | {
96 |
97 | NSFetchRequest *fetchRequest = [self fetchRequestWithEntityName:entityName
98 | predicate:predicate
99 | sortingKeys:sortingKeys
100 | ascending:ascending];
101 |
102 | NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
103 | managedObjectContext:self.mainManagedObjectContext
104 | sectionNameKeyPath:sectionKey
105 | cacheName:nil];
106 | fetchedResultsController.delegate = delegate;
107 |
108 | return fetchedResultsController;
109 | }
110 |
111 | /**
112 | * Creates a NSFetchRequest with a given entity name, predicate and sorting key.
113 | *
114 | * @param entityName The entity name of the fetched objects.
115 | * @param predicate The fetch predicate.
116 | * @param sortingKey The sorting key.
117 | * @param ascending YES - Ascending.
118 | *
119 | * @return NSFetchRequest instance.
120 | */
121 | - (NSFetchRequest *)fetchRequestWithEntityName:(NSString *)entityName
122 | predicate:(NSPredicate *)predicate
123 | sortingKeys:(NSArray *)sortingKeys
124 | ascending:(BOOL)ascending
125 | {
126 | NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
127 | fetchRequest.predicate = predicate;
128 | NSMutableArray *sortingDescriptors = [NSMutableArray arrayWithCapacity:[sortingKeys count]];
129 | // Create the sort descriptors
130 | for (NSString *sortingKey in sortingKeys) {
131 | NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:sortingKey ascending:ascending];
132 | [sortingDescriptors addObject:sortDescriptor];
133 | }
134 |
135 | fetchRequest.sortDescriptors = sortingDescriptors;
136 | fetchRequest.returnsObjectsAsFaults = NO;
137 |
138 | return fetchRequest;
139 | }
140 |
141 |
142 | #pragma mark - CoreData stack
143 |
144 | - (NSManagedObjectContext *)mainManagedObjectContext {
145 | if (_mainManagedObjectContext != nil) {
146 | return _mainManagedObjectContext;
147 | }
148 |
149 | NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
150 | if (coordinator != nil) {
151 | // Make sure the main object context executes on the main queue
152 | _mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
153 | [_mainManagedObjectContext setPersistentStoreCoordinator:coordinator];
154 | }
155 | return _mainManagedObjectContext;
156 | }
157 |
158 | - (NSManagedObjectContext*)backgroundQueueManagedObjectContext {
159 |
160 | // Make sure the background context executes on a private queue
161 | NSManagedObjectContext *backgroundQueueManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
162 | // Set the background context's parent to be the main context
163 | [backgroundQueueManagedObjectContext setParentContext:self.mainManagedObjectContext];
164 | [backgroundQueueManagedObjectContext setUndoManager:nil];
165 |
166 | return backgroundQueueManagedObjectContext;
167 | }
168 |
169 | - (NSManagedObjectModel *)managedObjectModel {
170 | if (_managedObjectModel != nil) {
171 | return _managedObjectModel;
172 | }
173 | NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
174 | _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
175 | return _managedObjectModel;
176 | }
177 |
178 | - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
179 | if (_persistentStoreCoordinator != nil) {
180 | return _persistentStoreCoordinator;
181 | }
182 |
183 | NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"JenkinsCI.sqlite"];
184 |
185 | NSError *error = nil;
186 | _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
187 | if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSPersistentStoreFileProtectionKey : NSFileProtectionComplete} error:&error]) {
188 |
189 | DDLogError(@"Unresolved error %@, %@", error, [error userInfo]);
190 | abort();
191 | }
192 |
193 | return _persistentStoreCoordinator;
194 | }
195 |
196 | #pragma mark - Application's Documents directory
197 |
198 | // Returns the URL to the application's Documents directory.
199 | - (NSURL *)applicationDocumentsDirectory {
200 | return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
201 | }
202 |
203 |
204 | @end
205 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataPlayerManger/CoreDataPlayerManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataPlayerManager.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "CoreDataEntityManager.h"
10 | #import "Player.h"
11 |
12 | @interface CoreDataPlayerManager : CoreDataEntityManager
13 |
14 | /**
15 | * Creates a Player entity object with a first name and a last name.
16 | *
17 | * @param firstName Player's first name.
18 | * @param lastName Player's last name.
19 | *
20 | * @return Player instance.
21 | */
22 | - (Player *)createPlayerWithFirstName:(NSString *)firstName
23 | lastName:(NSString *)lastName;
24 |
25 | /**
26 | * Deletes a Player entity from its managed object context.
27 | *
28 | * @param player Player instance.
29 | */
30 | - (void)deletePlayer:(Player *)player;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/CoreDataPlayerManger/CoreDataPlayerManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // CoreDataPlayerManager.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "CoreDataPlayerManager.h"
10 | #import "CoreDataManager.h"
11 |
12 | @implementation CoreDataPlayerManager
13 |
14 | - (Player *)createPlayerWithFirstName:(NSString *)firstName
15 | lastName:(NSString *)lastName
16 | {
17 | // Get the player class name
18 | NSString *playerClassName = NSStringFromClass([Player class]);
19 | // Get the main context
20 | NSManagedObjectContext *context = [[CoreDataManager sharedInstance] mainManagedObjectContext];
21 | // Create the entity
22 | Player *playerObject = (Player *)[self createNSManagedObjectWithEntityName:playerClassName
23 | onContext:context];
24 | // Set it's properties
25 | playerObject.firstName = firstName;
26 | playerObject.lastName = lastName;
27 |
28 | return playerObject;
29 | }
30 |
31 | - (void)deletePlayer:(Player *)player {
32 | [self deleteObject:player];
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/DataImporter/DataImporter.h:
--------------------------------------------------------------------------------
1 | //
2 | // DataImporter.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DataImporter : NSObject
12 |
13 | @property (nonatomic) BOOL didImportData;
14 |
15 | /**
16 | * Method that will import the players and club infos from an NSDictionary.
17 | *
18 | */
19 | - (void)importData;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Managers/DataImporter/DataImporter.m:
--------------------------------------------------------------------------------
1 | //
2 | // DataImporter.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "DataImporter.h"
10 | #import "CoreDataManager.h"
11 | #import "CoreDataClubManager.h"
12 | #import "CoreDataPlayerManager.h"
13 |
14 | // NSUserDefaults import key
15 | static NSString * const kDidImportDataKey = @"kDidImportData";
16 |
17 | // JSON import keys
18 | // Club
19 | static NSString * const kClubsKey = @"clubs";
20 | static NSString * const kClubId = @"clubId";
21 | static NSString * const kClubName = @"clubName";
22 | static NSString * const kClubStadiumName = @"stadiumName";
23 | // Player
24 | static NSString * const kPlayersKey = @"players";
25 | static NSString * const kPlayerId = @"playerId";
26 | static NSString * const kPlayerFirstName = @"firstName";
27 | static NSString * const kPlayerLastName = @"lastName";
28 | static NSString * const kPlayerPosition = @"position";
29 | static NSString * const kPlayerShirtNumber = @"shirtNumber";
30 | static NSString * const kPlayerClub = @"club";
31 |
32 | // JSON
33 | static NSString * const kJSonFileName = @"db";
34 | static NSString * const kJSonFileType = @"json";
35 |
36 | @interface DataImporter ()
37 |
38 | @property (nonatomic, strong) NSManagedObjectContext *importerContext;
39 | @property (nonatomic, strong) NSMutableDictionary *clubsById;
40 |
41 | @end
42 |
43 |
44 | @implementation DataImporter
45 |
46 |
47 | #pragma mark - Init
48 |
49 | - (instancetype)init {
50 | if (self = [super init]) {
51 | // Create a background context and asign it
52 | _importerContext = [[CoreDataManager sharedInstance] backgroundQueueManagedObjectContext];
53 | // Prepare a dictionary for clubs - clubId pairing
54 | _clubsById = [[NSMutableDictionary alloc] init];
55 | }
56 |
57 | return self;
58 | }
59 |
60 | #pragma mark - Importing data
61 |
62 | - (BOOL)didImportData {
63 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
64 | return [userDefaults boolForKey:kDidImportDataKey];
65 | }
66 |
67 | - (void)setDidImportData:(BOOL)didImportData {
68 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
69 | [userDefaults setBool:didImportData forKey:kDidImportDataKey];
70 | [userDefaults synchronize];
71 | }
72 |
73 | - (void)importData {
74 | NSDictionary *dictionary = [self jsonFileData];
75 | [self importDataFromDictionary:dictionary];
76 | }
77 |
78 | - (void)importDataFromDictionary:(NSDictionary *)dictionary {
79 |
80 | __weak typeof(self)weakSelf = self;
81 |
82 | [self.importerContext performBlockAndWait:^{
83 | // Create the clubs
84 | NSArray *clubs = [dictionary objectForKey:kClubsKey];
85 | [weakSelf createClubsUsingArray:clubs];
86 |
87 | // Create the players
88 | NSArray *players = [dictionary objectForKey:kPlayersKey];
89 | [weakSelf createPlayersUsingArray:players];
90 |
91 | __block NSError *error = nil;
92 | __block BOOL saved = [weakSelf.importerContext save:&error];
93 | if (saved && weakSelf.importerContext.parentContext) {
94 | [weakSelf.importerContext.parentContext performBlockAndWait:^{
95 | saved = [weakSelf.importerContext.parentContext save:&error];
96 | }];
97 | }
98 |
99 | if (!error) {
100 | // Mark data as imported
101 | [weakSelf setDidImportData:YES];
102 | } else {
103 | DDLogError(@"CoreData error: %@", error);
104 | }
105 |
106 | }];
107 | }
108 |
109 | #pragma mark - Club creation
110 |
111 | - (void)createClubsUsingArray:(NSArray *)clubs {
112 | NSAssert(([clubs count] > 0), @"The clubs array should not be empty.");
113 | // Create a CoreDataClubManager
114 | CoreDataClubManager *clubManager = [[CoreDataClubManager alloc] initWithContext:self.importerContext];
115 | // Create the clubs
116 | for (NSDictionary *clubInfo in clubs) {
117 | [self createClubWithDictionary:clubInfo
118 | usingClubManager:clubManager];
119 | }
120 | }
121 |
122 | - (void)createClubWithDictionary:(NSDictionary *)dictionary
123 | usingClubManager:(CoreDataClubManager *)clubManager
124 | {
125 | // Get the club data
126 | NSNumber *clubId = [dictionary objectForKey:kClubId];
127 | NSString *clubName = [dictionary objectForKey:kClubName];
128 | NSString *stadiumName = [dictionary objectForKey:kClubStadiumName];
129 |
130 | // Create the club
131 | Club * club = [clubManager createClubWithName:clubName
132 | clubId:clubId];
133 | club.stadiumName = stadiumName;
134 | // Create a club - club id pairing for easy player creation
135 | [self.clubsById setObject:club
136 | forKey:club.clubId];
137 | }
138 |
139 | #pragma mark - Player creation
140 |
141 | - (void)createPlayersUsingArray:(NSArray *)players {
142 | NSAssert(([players count] > 0), @"The players array should not be empty.");
143 | // Create a CoreDataPlayerManager
144 | CoreDataPlayerManager *playerManager = [[CoreDataPlayerManager alloc] initWithContext:self.importerContext];
145 | // Create the players
146 | for (NSDictionary *playerInfo in players) {
147 | [self createPlayerWithDictionary:playerInfo
148 | usingPlayerManager:playerManager];
149 | }
150 |
151 | }
152 |
153 | - (void)createPlayerWithDictionary:(NSDictionary *)dictionary
154 | usingPlayerManager:(CoreDataPlayerManager *)playerManager
155 | {
156 | // Get player info
157 | NSString *firstName = [dictionary objectForKey:kPlayerFirstName];
158 | NSString *lastName = [dictionary objectForKey:kPlayerLastName];
159 | NSNumber *clubId = [dictionary objectForKey:kPlayerClub];
160 | // Create player object
161 | Player *player = [playerManager createPlayerWithFirstName:firstName
162 | lastName:lastName];
163 | player.playerId = [dictionary objectForKey:kPlayerId];
164 | player.position = [dictionary objectForKey:kPlayerPosition];
165 | player.shirtNumber = [dictionary objectForKey:kPlayerShirtNumber];
166 |
167 | Club *club = [self.clubsById objectForKey:clubId];
168 | player.club = club;
169 |
170 | }
171 |
172 |
173 | #pragma mark - JSON file
174 |
175 | - (NSDictionary *)jsonFileData {
176 | NSString *filePath = [[NSBundle mainBundle] pathForResource:kJSonFileName
177 | ofType:kJSonFileType];
178 | NSString *myJSON = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
179 | NSError *error = nil;
180 | NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:[myJSON dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
181 | return jsonData;
182 | }
183 |
184 | @end
185 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Model/Club/Club.h:
--------------------------------------------------------------------------------
1 | //
2 | // Club.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class Player;
13 |
14 | @interface Club : NSManagedObject
15 |
16 | @property (nonatomic, retain) NSString * clubName;
17 | @property (nonatomic, retain) NSString * stadiumName;
18 | @property (nonatomic, retain) NSNumber * clubId;
19 | @property (nonatomic, retain) NSSet *squad;
20 | @end
21 |
22 | @interface Club (CoreDataGeneratedAccessors)
23 |
24 | - (void)addSquadObject:(Player *)value;
25 | - (void)removeSquadObject:(Player *)value;
26 | - (void)addSquad:(NSSet *)values;
27 | - (void)removeSquad:(NSSet *)values;
28 |
29 | @end
30 |
31 | @interface Club (Additions)
32 |
33 | - (UIImage *)logoImage;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Model/Club/Club.m:
--------------------------------------------------------------------------------
1 | //
2 | // Club.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "Club.h"
10 | #import "Player.h"
11 | #import
12 |
13 | @implementation Club
14 |
15 | @dynamic clubName;
16 | @dynamic stadiumName;
17 | @dynamic clubId;
18 | @dynamic squad;
19 |
20 | @end
21 |
22 | @implementation Club (Additions)
23 |
24 | - (UIImage *)logoImage {
25 | NSString *strippedString = [self.clubName stringByReplacingOccurrencesOfString:@" " withString:@"-"];
26 | NSString *imageName = [NSString stringWithFormat:@"%@-logo", strippedString];
27 | return [UIImage imageNamed:imageName];
28 | }
29 |
30 | @end
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Model/Player/Player.h:
--------------------------------------------------------------------------------
1 | //
2 | // Player.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class Club;
13 |
14 | @interface Player : NSManagedObject
15 |
16 | @property (nonatomic, retain) NSString * firstName;
17 | @property (nonatomic, retain) NSString * lastName;
18 | @property (nonatomic, retain) NSString * position;
19 | @property (nonatomic, retain) NSNumber * playerId;
20 | @property (nonatomic, retain) NSNumber * shirtNumber;
21 | @property (nonatomic, retain) Club *club;
22 |
23 | @end
24 |
25 | @interface Player (Additions)
26 |
27 | - (NSString *)playerFullName;
28 | - (UIImage *)playerImage;
29 |
30 | @end
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Model/Player/Player.m:
--------------------------------------------------------------------------------
1 | //
2 | // Player.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "Player.h"
10 | #import "Club.h"
11 | #import
12 |
13 | @implementation Player
14 |
15 | @dynamic firstName;
16 | @dynamic lastName;
17 | @dynamic position;
18 | @dynamic playerId;
19 | @dynamic shirtNumber;
20 | @dynamic club;
21 |
22 | @end
23 |
24 | @implementation Player (Additions)
25 |
26 |
27 | - (NSString *)playerFullName {
28 | return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
29 | }
30 |
31 | - (UIImage *)playerImage {
32 | NSString *strippedName = [[[self playerFullName] lowercaseString] stringByReplacingOccurrencesOfString:@" " withString:@"_"];
33 | return [UIImage imageNamed:strippedName];
34 | }
35 |
36 |
37 | @end
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Utils/UIImageView+RoundCorners/UIImageView+RoundCorners.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageView+RoundCorners.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImageView (RoundCorners)
12 |
13 | /**
14 | * Applies a corner radius to a given UIImageView with a border
15 | * with and color.
16 | *
17 | * @param radius Radius value.
18 | * @param border Border width.
19 | * @param color Border color.
20 | */
21 | - (void)applyCornerRadius:(CGFloat)radius
22 | borderWidth:(CGFloat)border
23 | borderColor:(UIColor *)color;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/Utils/UIImageView+RoundCorners/UIImageView+RoundCorners.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImageView+RoundCorners.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 20/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "UIImageView+RoundCorners.h"
10 | @import QuartzCore;
11 |
12 | @implementation UIImageView (RoundCorners)
13 |
14 | - (void)applyCornerRadius:(CGFloat)radius
15 | borderWidth:(CGFloat)border
16 | borderColor:(UIColor *)color
17 | {
18 | self.layer.cornerRadius = radius;
19 | self.clipsToBounds = YES;
20 | self.layer.borderColor = color.CGColor;
21 | self.layer.borderWidth = border;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/ClubTableViewCell/ClubTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ClubTableViewCell.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ClubTableViewCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *clubNameLabel;
14 | @property (weak, nonatomic) IBOutlet UILabel *squadSizeLabel;
15 | @property (weak, nonatomic) IBOutlet UIImageView *clubLogoView;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/ClubTableViewCell/ClubTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ClubTableViewCell.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "ClubTableViewCell.h"
10 |
11 | @implementation ClubTableViewCell
12 |
13 | - (void)awakeFromNib {
14 | // Initialization code
15 | }
16 |
17 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
18 | [super setSelected:selected animated:animated];
19 |
20 | // Configure the view for the selected state
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/PlayerTableViewCell/PlayerTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // PlayerTableViewCell.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PlayerTableViewCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *playerFullNameLabel;
14 | @property (weak, nonatomic) IBOutlet UILabel *clubNameLabel;
15 | @property (weak, nonatomic) IBOutlet UILabel *playerPositionLabel;
16 | @property (weak, nonatomic) IBOutlet UIImageView *playerImageView;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/PlayerTableViewCell/PlayerTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // PlayerTableViewCell.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "PlayerTableViewCell.h"
10 | #import "UIImageView+RoundCorners.h"
11 |
12 | @implementation PlayerTableViewCell
13 |
14 | - (void)awakeFromNib {
15 | // Initialization code
16 |
17 | CGFloat width = CGRectGetWidth(self.playerImageView.frame);
18 | [self.playerImageView applyCornerRadius:width/2
19 | borderWidth:1.0
20 | borderColor:[UIColor darkGrayColor]];
21 | }
22 |
23 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
24 | [super setSelected:selected animated:animated];
25 |
26 | // Configure the view for the selected state
27 | }
28 |
29 | //- (void)layoutSubviews {
30 | // [super layoutSubviews];
31 | //}
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/SquadProfileTableViewCell/SquadProfileTableViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // SquadProfileTableViewCell.h
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SquadProfileTableViewCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *playerFullNameLabel;
14 | @property (weak, nonatomic) IBOutlet UILabel *playerPositionLabel;
15 | @property (weak, nonatomic) IBOutlet UILabel *playerNumberLabel;
16 | @property (weak, nonatomic) IBOutlet UIImageView *playerPictureView;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/JenkinsCI/Classes/View/SquadProfileTableViewCell/SquadProfileTableViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // SquadProfileTableViewCell.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 17/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import "SquadProfileTableViewCell.h"
10 | #import "UIImageView+RoundCorners.h"
11 |
12 | @implementation SquadProfileTableViewCell
13 |
14 | - (void)awakeFromNib {
15 | // Initialization code
16 | CGFloat width = CGRectGetWidth(self.playerPictureView.frame);
17 | [self.playerPictureView applyCornerRadius:width/2
18 | borderWidth:1.0
19 | borderColor:[UIColor darkGrayColor]];
20 | }
21 |
22 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
23 | [super setSelected:selected animated:animated];
24 |
25 | // Configure the view for the selected state
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/JenkinsCI/CoreData/Model.xcdatamodeld/Model.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/JenkinsCI/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.endava.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 0.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarTintParameters
34 |
35 | UINavigationBar
36 |
37 | Style
38 | UIBarStyleDefault
39 | Translucent
40 |
41 |
42 |
43 | UISupportedInterfaceOrientations
44 |
45 | UIInterfaceOrientationPortrait
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/JenkinsCI/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // PrefixHeader.pch
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #ifndef JenkinsCI_PrefixHeader_pch
10 | #define JenkinsCI_PrefixHeader_pch
11 |
12 | // Include any system framework and library headers here that should be included in all compilation units.
13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
14 | #import
15 |
16 |
17 | // CocoaLumberjack log levels.
18 | #ifdef DEBUG
19 | static const int ddLogLevel = LOG_LEVEL_INFO;
20 | #else
21 | static const int ddLogLevel = LOG_LEVEL_WARN;
22 | #endif
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "29x29",
41 | "idiom" : "ipad",
42 | "filename" : "Icon-Small.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "29x29",
47 | "idiom" : "ipad",
48 | "filename" : "Icon-Small@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "40x40",
53 | "idiom" : "ipad",
54 | "filename" : "Icon-40.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "40x40",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-40@2x.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "76x76",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-76.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "76x76",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-76@2x.png",
73 | "scale" : "2x"
74 | }
75 | ],
76 | "info" : {
77 | "version" : 1,
78 | "author" : "xcode"
79 | }
80 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Arsenal-FC-logo.imageset/Arsenal-FC-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/club-logos/Arsenal-FC-logo.imageset/Arsenal-FC-icon.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Arsenal-FC-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Arsenal-FC-icon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Chelsea-FC-logo.imageset/Chelsea-FC-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/club-logos/Chelsea-FC-logo.imageset/Chelsea-FC-icon.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Chelsea-FC-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Chelsea-FC-icon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Everton-FC-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Everton-FC-icon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Everton-FC-logo.imageset/Everton-FC-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/club-logos/Everton-FC-logo.imageset/Everton-FC-icon.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Liverpool-FC-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Liverpool-FC-icon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Liverpool-FC-logo.imageset/Liverpool-FC-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/club-logos/Liverpool-FC-logo.imageset/Liverpool-FC-icon.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Manchester-United-logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Manchester-United-icon.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/club-logos/Manchester-United-logo.imageset/Manchester-United-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/club-logos/Manchester-United-logo.imageset/Manchester-United-icon.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/persons.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "persons@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x",
15 | "filename" : "persons@3x.png"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/persons.imageset/persons@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/persons.imageset/persons@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/persons.imageset/persons@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/persons.imageset/persons@3x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/aaron_ramsey.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "aaron_ramsey.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/aaron_ramsey.imageset/aaron_ramsey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/aaron_ramsey.imageset/aaron_ramsey.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/angel_di_maria.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "angel_di_maria.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/angel_di_maria.imageset/angel_di_maria.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/angel_di_maria.imageset/angel_di_maria.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/daniel_sturridge.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "daniel_sturridge.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/daniel_sturridge.imageset/daniel_sturridge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/daniel_sturridge.imageset/daniel_sturridge.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/eden_hazard.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "eden_hazard.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/eden_hazard.imageset/eden_hazard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/eden_hazard.imageset/eden_hazard.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/jordan_henderson.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "jordan_henderson.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/jordan_henderson.imageset/jordan_henderson.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/jordan_henderson.imageset/jordan_henderson.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/martin_skrtel.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "martin_skrtel.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/martin_skrtel.imageset/martin_skrtel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/martin_skrtel.imageset/martin_skrtel.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/player_placeholder.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "player_placeholder.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/player_placeholder.imageset/player_placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/player_placeholder.imageset/player_placeholder.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/ross_barkley.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "ross_barkley.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/ross_barkley.imageset/ross_barkley.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/ross_barkley.imageset/ross_barkley.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/steven_gerrard.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "steven_gerrard.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/steven_gerrard.imageset/steven_gerrard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/steven_gerrard.imageset/steven_gerrard.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/wayne_rooney.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "wayne_rooney.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/player-pictures/wayne_rooney.imageset/wayne_rooney.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/player-pictures/wayne_rooney.imageset/wayne_rooney.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/stadium.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "stadium@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x",
15 | "filename" : "stadium@3x.png"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/stadium.imageset/stadium@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/stadium.imageset/stadium@2x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/Images.xcassets/stadium.imageset/stadium@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/JenkinsCI/Resources/Images.xcassets/stadium.imageset/stadium@3x.png
--------------------------------------------------------------------------------
/JenkinsCI/Resources/db.json:
--------------------------------------------------------------------------------
1 | { "clubs" : [ { "clubId" : 101,
2 | "clubName" : "Liverpool FC",
3 | "stadiumName" : "Anfield"
4 | },
5 | { "clubId" : 102,
6 | "clubName" : "Manchester United",
7 | "stadiumName" : "Old Trafford"
8 | },
9 | { "clubId" : 103,
10 | "clubName" : "Arsenal FC",
11 | "stadiumName" : "Emirates Stadium"
12 | },
13 | { "clubId" : 104,
14 | "clubName" : "Chelsea FC",
15 | "stadiumName" : "Stamford Bridge"
16 | },
17 | { "clubId" : 105,
18 | "clubName" : "Everton FC",
19 | "stadiumName" : "Stamford Bridge"
20 | }
21 | ],
22 | "players" : [ { "club" : 101,
23 | "firstName" : "Steven",
24 | "lastName" : "Gerrard",
25 | "playerId" : 100001,
26 | "position" : "Midfielder",
27 | "shirtNumber" : 8
28 | },
29 | { "club" : 101,
30 | "firstName" : "Jordan",
31 | "lastName" : "Henderson",
32 | "playerId" : 100002,
33 | "position" : "Midfielder",
34 | "shirtNumber" : 14
35 | },
36 | { "club" : 101,
37 | "firstName" : "Daniel",
38 | "lastName" : "Sturridge",
39 | "playerId" : 100003,
40 | "position" : "Striker",
41 | "shirtNumber" : 15
42 | },
43 | { "club" : 101,
44 | "firstName" : "Martin",
45 | "lastName" : "Skrtel",
46 | "playerId" : 100004,
47 | "position" : "Defender",
48 | "shirtNumber" : 37
49 | },
50 | { "club" : 105,
51 | "firstName" : "Ross",
52 | "lastName" : "Barkley",
53 | "playerId" : 100005,
54 | "position" : "Midfielder",
55 | "shirtNumber" : 20
56 | },
57 | { "club" : 102,
58 | "firstName" : "Angel",
59 | "lastName" : "Di Maria",
60 | "playerId" : 100006,
61 | "position" : "Midfielder",
62 | "shirtNumber" : 7
63 | },
64 | { "club" : 102,
65 | "firstName" : "Wayne",
66 | "lastName" : "Rooney",
67 | "playerId" : 100007,
68 | "position" : "Striker",
69 | "shirtNumber" : 10
70 | },
71 | { "club" : 103,
72 | "firstName" : "Aaron",
73 | "lastName" : "Ramsey",
74 | "playerId" : 100007,
75 | "position" : "Midfielder",
76 | "shirtNumber" : 16
77 | },
78 | { "club" : 104,
79 | "firstName" : "Eden",
80 | "lastName" : "Hazard",
81 | "playerId" : 100008,
82 | "position" : "Midfielder",
83 | "shirtNumber" : 10
84 | }
85 | ]
86 | }
--------------------------------------------------------------------------------
/JenkinsCI/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // JenkinsCI
4 | //
5 | // Created by Ciprian Redinciuc on 14/10/14.
6 | // Copyright (c) 2014 Ciprian Redinciuc. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/JenkinsCITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.endava.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 | platform :ios, '7.0'
3 |
4 |
5 | pod 'CocoaLumberjack'
6 | pod 'CrashlyticsFramework'
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CocoaLumberjack (2.0.0-beta2):
3 | - CocoaLumberjack/CLI
4 | - CocoaLumberjack/Core
5 | - CocoaLumberjack/Extensions
6 | - CocoaLumberjack/CLI (2.0.0-beta2):
7 | - CocoaLumberjack/Core
8 | - CocoaLumberjack/Core (2.0.0-beta2)
9 | - CocoaLumberjack/Extensions (2.0.0-beta2):
10 | - CocoaLumberjack/Core
11 | - CrashlyticsFramework (2.2.5)
12 |
13 | DEPENDENCIES:
14 | - CocoaLumberjack
15 | - CrashlyticsFramework
16 |
17 | SPEC CHECKSUMS:
18 | CocoaLumberjack: 956d3fb98fed498a13d56499f262c975ef431c98
19 | CrashlyticsFramework: 82d124501d97d3b5d49bd6209dea21c6b7f0a33d
20 |
21 | COCOAPODS: 0.34.4
22 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/CLI/CLIColor.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import
17 |
18 | /**
19 | * This class represents an NSColor replacement for CLI projects that don't link with AppKit
20 | **/
21 |
22 | @interface CLIColor : NSObject
23 |
24 | + (CLIColor *)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
25 | - (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/CLI/CLIColor.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "CLIColor.h"
17 |
18 | @interface CLIColor () {
19 | CGFloat _red, _green, _blue, _alpha;
20 | }
21 |
22 | @end
23 |
24 |
25 | @implementation CLIColor
26 |
27 | + (CLIColor *)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {
28 | CLIColor *color = [CLIColor new];
29 |
30 | color->_red = red;
31 | color->_green = green;
32 | color->_blue = blue;
33 | color->_alpha = alpha;
34 | return color;
35 | }
36 |
37 | - (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha {
38 | if (red) {
39 | *red = _red;
40 | }
41 |
42 | if (green) {
43 | *green = _green;
44 | }
45 |
46 | if (blue) {
47 | *blue = _blue;
48 | }
49 |
50 | if (alpha) {
51 | *alpha = _alpha;
52 | }
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/CocoaLumberjack.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | /**
17 | * Welcome to CocoaLumberjack!
18 | *
19 | * The project page has a wealth of documentation if you have any questions.
20 | * https://github.com/CocoaLumberjack/CocoaLumberjack
21 | *
22 | * If you're new to the project you may wish to read "Getting Started" at:
23 | * Documentation/GettingStarted.md
24 | *
25 | * Otherwise, here is a quick refresher.
26 | * There are three steps to using the macros:
27 | *
28 | * Step 1:
29 | * Import the header in your implementation or prefix file:
30 | *
31 | * #import
32 | *
33 | * Step 2:
34 | * Define your logging level in your implementation file:
35 | *
36 | * // Log levels: off, error, warn, info, verbose
37 | * static const int ddLogLevel = LOG_LEVEL_VERBOSE;
38 | *
39 | * Step 2 [3rd party frameworks]:
40 | *
41 | * Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel:
42 | *
43 | * // #undef LOG_LEVEL_DEF // Undefine first only if needed
44 | * #define LOG_LEVEL_DEF myLibLogLevel
45 | *
46 | * Define your logging level in your implementation file:
47 | *
48 | * // Log levels: off, error, warn, info, verbose
49 | * static const int myLibLogLevel = LOG_LEVEL_VERBOSE;
50 | *
51 | * Step 3:
52 | * Replace your NSLog statements with DDLog statements according to the severity of the message.
53 | *
54 | * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!");
55 | *
56 | * DDLog works exactly the same as NSLog.
57 | * This means you can pass it multiple variables just like NSLog.
58 | **/
59 |
60 | #import "DDLog.h"
61 | #import "DDLogMacros.h"
62 | #import "DDAssertMacros.h"
63 |
64 | // Loggers
65 | #import "DDTTYLogger.h"
66 | #import "DDASLLogger.h"
67 | #import "DDFileLogger.h"
68 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDASLLogCapture.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDASLLogger.h"
17 |
18 | @protocol DDLogger;
19 |
20 | /**
21 | * This class provides the ability to capture the ASL (Apple System Logs)
22 | */
23 | @interface DDASLLogCapture : NSObject
24 |
25 | + (void)start;
26 | + (void)stop;
27 |
28 | // Default log level: LOG_LEVEL_VERBOSE (i.e. capture all ASL messages).
29 | + (int)captureLogLevel;
30 | + (void)setCaptureLogLevel:(int)LOG_LEVEL_XXX;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDASLLogCapture.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDASLLogCapture.h"
17 | #import "DDLog.h"
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | static BOOL _cancel = YES;
25 | static int _captureLogLevel = LOG_LEVEL_VERBOSE;
26 |
27 | @implementation DDASLLogCapture
28 |
29 | + (void)start {
30 | // Ignore subsequent calls
31 | if (!_cancel) {
32 | return;
33 | }
34 |
35 | _cancel = NO;
36 |
37 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
38 | [DDASLLogCapture captureAslLogs];
39 | });
40 | }
41 |
42 | + (void)stop {
43 | _cancel = YES;
44 | }
45 |
46 | + (int)captureLogLevel {
47 | return _captureLogLevel;
48 | }
49 |
50 | + (void)setCaptureLogLevel:(int)LOG_LEVEL_XXX {
51 | _captureLogLevel = LOG_LEVEL_XXX;
52 | }
53 |
54 | # pragma mark - Private methods
55 |
56 | + (void)configureAslQuery:(aslmsg)query {
57 | const char param[] = "7"; // ASL_LEVEL_DEBUG, which is everything. We'll rely on regular DDlog log level to filter
58 |
59 | asl_set_query(query, ASL_KEY_LEVEL, param, ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC);
60 |
61 | #if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
62 | int processId = [[NSProcessInfo processInfo] processIdentifier];
63 | char pid[16];
64 | sprintf(pid, "%d", processId);
65 | asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC);
66 | #endif
67 | }
68 |
69 | + (void)aslMessageRecieved:(aslmsg)msg {
70 | // NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding];
71 | NSString *message = [NSString stringWithCString:asl_get(msg, ASL_KEY_MSG) encoding:NSUTF8StringEncoding];
72 | NSString *level = [NSString stringWithCString:asl_get(msg, ASL_KEY_LEVEL) encoding:NSUTF8StringEncoding];
73 | NSString *secondsStr = [NSString stringWithCString:asl_get(msg, ASL_KEY_TIME) encoding:NSUTF8StringEncoding];
74 | NSString *nanoStr = [NSString stringWithCString:asl_get(msg, ASL_KEY_TIME_NSEC) encoding:NSUTF8StringEncoding];
75 |
76 | NSTimeInterval seconds = [secondsStr doubleValue];
77 | NSTimeInterval nanoSeconds = [nanoStr doubleValue];
78 | NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9);
79 |
80 | NSDate *timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
81 |
82 | int flag;
83 | BOOL async;
84 |
85 | switch ([level intValue]) {
86 | // By default all NSLog's with a ASL_LEVEL_WARNING level
87 | case ASL_LEVEL_EMERG :
88 | case ASL_LEVEL_ALERT :
89 | case ASL_LEVEL_CRIT : flag = LOG_FLAG_ERROR; async = LOG_ASYNC_ERROR; break;
90 | case ASL_LEVEL_ERR : flag = LOG_FLAG_WARN; async = LOG_ASYNC_WARN; break;
91 | case ASL_LEVEL_WARNING : flag = LOG_FLAG_INFO; async = LOG_ASYNC_INFO; break;
92 | case ASL_LEVEL_NOTICE : flag = LOG_FLAG_DEBUG; async = LOG_ASYNC_DEBUG; break;
93 | case ASL_LEVEL_INFO :
94 | case ASL_LEVEL_DEBUG :
95 | default : flag = LOG_FLAG_VERBOSE; async = LOG_ASYNC_VERBOSE; break;
96 | }
97 |
98 | if (!(_captureLogLevel & flag)) {
99 | return;
100 | }
101 |
102 | DDLogMessage *logMessage = [[DDLogMessage alloc]initWithLogMsg:message
103 | level:_captureLogLevel
104 | flag:flag
105 | context:0
106 | file:"DDASLLogCapture"
107 | function:0
108 | line:0
109 | tag:nil
110 | options:0
111 | timestamp:timeStamp];
112 |
113 | [DDLog log:async message:logMessage];
114 | }
115 |
116 | + (void)captureAslLogs {
117 | @autoreleasepool
118 | {
119 | /*
120 | We use ASL_KEY_MSG_ID to see each message once, but there's no
121 | obvious way to get the "next" ID. To bootstrap the process, we'll
122 | search by timestamp until we've seen a message.
123 | */
124 |
125 | struct timeval timeval = {
126 | .tv_sec = 0
127 | };
128 | gettimeofday(&timeval, NULL);
129 | unsigned long long startTime = timeval.tv_sec;
130 | __block unsigned long long lastSeenID = 0;
131 |
132 | /*
133 | syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
134 | through the notify API when it saves messages to the ASL database.
135 | There is some coalescing - currently it is sent at most twice per
136 | second - but there is no documented guarantee about this. In any
137 | case, there may be multiple messages per notification.
138 |
139 | Notify notifications don't carry any payload, so we need to search
140 | for the messages.
141 | */
142 | int notifyToken = 0; // Can be used to unregister with notify_cancel().
143 | notify_register_dispatch(kNotifyASLDBUpdate, ¬ifyToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int token)
144 | {
145 | // At least one message has been posted; build a search query.
146 | @autoreleasepool
147 | {
148 | aslmsg query = asl_new(ASL_TYPE_QUERY);
149 | char stringValue[64];
150 |
151 | if (lastSeenID > 0) {
152 | snprintf(stringValue, sizeof stringValue, "%llu", lastSeenID);
153 | asl_set_query(query, ASL_KEY_MSG_ID, stringValue, ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC);
154 | } else {
155 | snprintf(stringValue, sizeof stringValue, "%llu", startTime);
156 | asl_set_query(query, ASL_KEY_TIME, stringValue, ASL_QUERY_OP_GREATER_EQUAL | ASL_QUERY_OP_NUMERIC);
157 | }
158 |
159 | [DDASLLogCapture configureAslQuery:query];
160 |
161 | // Iterate over new messages.
162 | aslmsg msg;
163 | aslresponse response = asl_search(NULL, query);
164 | #if defined(__IPHONE_8_0) || defined(__MAC_10_10)
165 |
166 | while ((msg = asl_next(response)))
167 | #else
168 |
169 | while ((msg = aslresponse_next(response)))
170 | #endif
171 | {
172 | [DDASLLogCapture aslMessageRecieved:msg];
173 |
174 | // Keep track of which messages we've seen.
175 | lastSeenID = atoll(asl_get(msg, ASL_KEY_MSG_ID));
176 | }
177 | #if defined(__IPHONE_8_0) || defined(__MAC_10_10)
178 | asl_release(response);
179 | #else
180 | aslresponse_free(response);
181 | #endif
182 |
183 | if (_cancel) {
184 | notify_cancel(notifyToken);
185 | return;
186 | }
187 |
188 | free(query);
189 | }
190 | });
191 | }
192 | }
193 |
194 | @end
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDASLLogger.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import
17 | #import "DDLog.h"
18 |
19 | /**
20 | * This class provides a logger for the Apple System Log facility.
21 | *
22 | * As described in the "Getting Started" page,
23 | * the traditional NSLog() function directs it's output to two places:
24 | *
25 | * - Apple System Log
26 | * - StdErr (if stderr is a TTY) so log statements show up in Xcode console
27 | *
28 | * To duplicate NSLog() functionality you can simply add this logger and a tty logger.
29 | * However, if you instead choose to use file logging (for faster performance),
30 | * you may choose to use a file logger and a tty logger.
31 | **/
32 |
33 | @interface DDASLLogger : DDAbstractLogger
34 |
35 | + (instancetype)sharedInstance;
36 |
37 | // Inherited from DDAbstractLogger
38 |
39 | // - (id )logFormatter;
40 | // - (void)setLogFormatter:(id )formatter;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDASLLogger.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDASLLogger.h"
17 | #import
18 |
19 | #if !__has_feature(objc_arc)
20 | #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
21 | #endif
22 |
23 | static DDASLLogger *sharedInstance;
24 |
25 | @interface DDASLLogger () {
26 | aslclient _client;
27 | }
28 |
29 | @end
30 |
31 |
32 | @implementation DDASLLogger
33 |
34 | + (instancetype)sharedInstance {
35 | static dispatch_once_t DDASLLoggerOnceToken;
36 |
37 | dispatch_once(&DDASLLoggerOnceToken, ^{
38 | sharedInstance = [[[self class] alloc] init];
39 | });
40 |
41 | return sharedInstance;
42 | }
43 |
44 | - (id)init {
45 | if (sharedInstance != nil) {
46 | return nil;
47 | }
48 |
49 | if ((self = [super init])) {
50 | // A default asl client is provided for the main thread,
51 | // but background threads need to create their own client.
52 |
53 | _client = asl_open(NULL, "com.apple.console", 0);
54 | }
55 |
56 | return self;
57 | }
58 |
59 | - (void)logMessage:(DDLogMessage *)logMessage {
60 | // Skip captured log messages.
61 | if (strcmp(logMessage->file, "DDASLLogCapture") == 0) {
62 | return;
63 | }
64 |
65 | NSString *logMsg = logMessage->logMsg;
66 |
67 | if (formatter) {
68 | logMsg = [formatter formatLogMessage:logMessage];
69 | }
70 |
71 | if (logMsg) {
72 | const char *msg = [logMsg UTF8String];
73 |
74 | size_t aslLogLevel;
75 | switch (logMessage->logFlag) {
76 | // Note: By default ASL will filter anything above level 5 (Notice).
77 | // So our mappings shouldn't go above that level.
78 | case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break;
79 | case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break;
80 | case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break; // Regular NSLog's level
81 | case LOG_FLAG_DEBUG :
82 | case LOG_FLAG_VERBOSE :
83 | default : aslLogLevel = ASL_LEVEL_NOTICE; break;
84 | }
85 |
86 | static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" };
87 |
88 | // NSLog uses the current euid to set the ASL_KEY_READ_UID.
89 | uid_t const readUID = geteuid();
90 |
91 | char readUIDString[16];
92 | int l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
93 |
94 | NSAssert(l < sizeof(readUIDString),
95 | @"Formatted euid is too long.");
96 | NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])),
97 | @"Unhandled ASL log level.");
98 |
99 | aslmsg m = asl_new(ASL_TYPE_MSG);
100 | if (m != NULL) {
101 | if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 &&
102 | asl_set(m, ASL_KEY_MSG, msg) == 0 &&
103 | asl_set(m, ASL_KEY_READ_UID, readUIDString) == 0) {
104 | asl_send(_client, m);
105 | }
106 | asl_free(m);
107 | }
108 | //TODO handle asl_* failures non-silently?
109 | }
110 | }
111 |
112 | - (NSString *)loggerName {
113 | return @"cocoa.lumberjack.aslLogger";
114 | }
115 |
116 | @end
117 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDAbstractDatabaseLogger.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDLog.h"
17 |
18 | /**
19 | * This class provides an abstract implementation of a database logger.
20 | *
21 | * That is, it provides the base implementation for a database logger to build atop of.
22 | * All that is needed for a concrete database logger is to extend this class
23 | * and override the methods in the implementation file that are prefixed with "db_".
24 | **/
25 |
26 | @interface DDAbstractDatabaseLogger : DDAbstractLogger {
27 |
28 | @protected
29 | NSUInteger _saveThreshold;
30 | NSTimeInterval _saveInterval;
31 | NSTimeInterval _maxAge;
32 | NSTimeInterval _deleteInterval;
33 | BOOL _deleteOnEverySave;
34 |
35 | BOOL _saveTimerSuspended;
36 | NSUInteger _unsavedCount;
37 | dispatch_time_t _unsavedTime;
38 | dispatch_source_t _saveTimer;
39 | dispatch_time_t _lastDeleteTime;
40 | dispatch_source_t _deleteTimer;
41 | }
42 |
43 | /**
44 | * Specifies how often to save the data to disk.
45 | * Since saving is an expensive operation (disk io) it is not done after every log statement.
46 | * These properties allow you to configure how/when the logger saves to disk.
47 | *
48 | * A save is done when either (whichever happens first):
49 | *
50 | * - The number of unsaved log entries reaches saveThreshold
51 | * - The amount of time since the oldest unsaved log entry was created reaches saveInterval
52 | *
53 | * You can optionally disable the saveThreshold by setting it to zero.
54 | * If you disable the saveThreshold you are entirely dependent on the saveInterval.
55 | *
56 | * You can optionally disable the saveInterval by setting it to zero (or a negative value).
57 | * If you disable the saveInterval you are entirely dependent on the saveThreshold.
58 | *
59 | * It's not wise to disable both saveThreshold and saveInterval.
60 | *
61 | * The default saveThreshold is 500.
62 | * The default saveInterval is 60 seconds.
63 | **/
64 | @property (assign, readwrite) NSUInteger saveThreshold;
65 | @property (assign, readwrite) NSTimeInterval saveInterval;
66 |
67 | /**
68 | * It is likely you don't want the log entries to persist forever.
69 | * Doing so would allow the database to grow infinitely large over time.
70 | *
71 | * The maxAge property provides a way to specify how old a log statement can get
72 | * before it should get deleted from the database.
73 | *
74 | * The deleteInterval specifies how often to sweep for old log entries.
75 | * Since deleting is an expensive operation (disk io) is is done on a fixed interval.
76 | *
77 | * An alternative to the deleteInterval is the deleteOnEverySave option.
78 | * This specifies that old log entries should be deleted during every save operation.
79 | *
80 | * You can optionally disable the maxAge by setting it to zero (or a negative value).
81 | * If you disable the maxAge then old log statements are not deleted.
82 | *
83 | * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
84 | *
85 | * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
86 | *
87 | * It's not wise to enable both deleteInterval and deleteOnEverySave.
88 | *
89 | * The default maxAge is 7 days.
90 | * The default deleteInterval is 5 minutes.
91 | * The default deleteOnEverySave is NO.
92 | **/
93 | @property (assign, readwrite) NSTimeInterval maxAge;
94 | @property (assign, readwrite) NSTimeInterval deleteInterval;
95 | @property (assign, readwrite) BOOL deleteOnEverySave;
96 |
97 | /**
98 | * Forces a save of any pending log entries (flushes log entries to disk).
99 | **/
100 | - (void)savePendingLogEntries;
101 |
102 | /**
103 | * Removes any log entries that are older than maxAge.
104 | **/
105 | - (void)deleteOldLogEntries;
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDAssertMacros.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDLogMacros.h"
17 |
18 | /**
19 | * NSAsset replacement that will output a log message even when assertions are disabled.
20 | **/
21 |
22 | #define DDAssert(condition, frmt, ...) \
23 | if (!(condition)) { \
24 | NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \
25 | DDLogError(@"%@", description); \
26 | NSAssert(NO, description); \
27 | }
28 |
29 | #define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition)
30 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDLog+LOGV.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #ifndef Lumberjack_DDLog_LOGV_h
17 | #define Lumberjack_DDLog_LOGV_h
18 |
19 | #import "DDLog.h"
20 |
21 |
22 | #define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist) \
23 | [DDLog log:isAsynchronous \
24 | level:lvl \
25 | flag:flg \
26 | context:ctx \
27 | file:__FILE__ \
28 | function:fnct \
29 | line:__LINE__ \
30 | tag:atag \
31 | format:frmt \
32 | args:avalist]
33 |
34 | #define LOGV_OBJC_MACRO(async, lvl, flg, ctx, frmt, avalist) \
35 | LOGV_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, avalist)
36 |
37 | #define LOGV_C_MACRO(async, lvl, flg, ctx, frmt, avalist) \
38 | LOGV_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, avalist)
39 |
40 |
41 |
42 | #define SYNC_LOGV_OBJC_MACRO(lvl, flg, ctx, frmt, avalist) \
43 | LOGV_OBJC_MACRO(NO, lvl, flg, ctx, frmt, avalist)
44 |
45 | #define ASYNC_LOGV_OBJC_MACRO(lvl, flg, ctx, frmt, avalist) \
46 | LOGV_OBJC_MACRO(YES, lvl, flg, ctx, frmt, avalist)
47 |
48 | #define SYNC_LOGV_C_MACRO(lvl, flg, ctx, frmt, avalist) \
49 | LOGV_C_MACRO(NO, lvl, flg, ctx, frmt, avalist)
50 |
51 | #define ASYNC_LOGV_C_MACRO(lvl, flg, ctx, frmt, avalist) \
52 | LOGV_C_MACRO(YES, lvl, flg, ctx, frmt, avalist)
53 |
54 |
55 |
56 | #define LOGV_MAYBE(async, lvl, flg, ctx, fnct, frmt, avalist) \
57 | do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, avalist); } while(0)
58 |
59 |
60 | #define LOGV_OBJC_MAYBE(async, lvl, flg, ctx, frmt, avalist) \
61 | LOGV_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, avalist)
62 |
63 | #define LOGV_C_MAYBE(async, lvl, flg, ctx, frmt, avalist) \
64 | LOGV_MAYBE(async, lvl, flg, ctx, __FUNCTION__, frmt, avalist)
65 |
66 | #define SYNC_LOGV_OBJC_MAYBE(lvl, flg, ctx, frmt, avalist) \
67 | LOGV_OBJC_MAYBE(NO, lvl, flg, ctx, frmt, avalist)
68 |
69 | #define ASYNC_LOGV_OBJC_MAYBE(lvl, flg, ctx, frmt, avalist) \
70 | LOGV_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, avalist)
71 |
72 | #define SYNC_LOGV_C_MAYBE(lvl, flg, ctx, frmt, avalist) \
73 | LOGV_C_MAYBE(NO, lvl, flg, ctx, frmt, avalist)
74 |
75 | #define ASYNC_LOGV_C_MAYBE(lvl, flg, ctx, frmt, avalist) \
76 | LOGV_C_MAYBE(YES, lvl, flg, ctx, frmt, avalist)
77 |
78 |
79 |
80 | #define LOGV_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, avalist) \
81 | LOGV_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, avalist)
82 |
83 | #define LOGV_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, avalist) \
84 | LOGV_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, avalist)
85 |
86 | #define LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, avalist) \
87 | do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, avalist); } while(0)
88 |
89 | #define LOGV_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, avalist) \
90 | LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, avalist)
91 |
92 | #define LOGV_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, avalist) \
93 | LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, avalist)
94 |
95 |
96 |
97 | #define DDLogvError(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, avalist)
98 | #define DDLogvWarn(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, avalist)
99 | #define DDLogvInfo(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, avalist)
100 | #define DDLogvVerbose(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, avalist)
101 |
102 | #define DDLogvCError(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, avalist)
103 | #define DDLogvCWarn(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, avalist)
104 | #define DDLogvCInfo(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, avalist)
105 | #define DDLogvCVerbose(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, avalist)
106 |
107 | #endif /* ifndef Lumberjack_DDLog_LOGV_h */
108 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDLogMacros.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDLog.h"
17 |
18 | /**
19 | * Ready to use log macros.
20 | **/
21 |
22 | #ifndef LOG_LEVEL_DEF
23 | #define LOG_LEVEL_DEF ddLogLevel
24 | #endif
25 |
26 | #define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ## __VA_ARGS__)
27 | #define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ## __VA_ARGS__)
28 | #define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ## __VA_ARGS__)
29 | #define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ## __VA_ARGS__)
30 | #define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ## __VA_ARGS__)
31 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/DDTTYLogger.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDLog.h"
17 |
18 | #define LOG_CONTEXT_ALL INT_MAX
19 |
20 | /**
21 | * This class provides a logger for Terminal output or Xcode console output,
22 | * depending on where you are running your code.
23 | *
24 | * As described in the "Getting Started" page,
25 | * the traditional NSLog() function directs it's output to two places:
26 | *
27 | * - Apple System Log (so it shows up in Console.app)
28 | * - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
29 | *
30 | * To duplicate NSLog() functionality you can simply add this logger and an asl logger.
31 | * However, if you instead choose to use file logging (for faster performance),
32 | * you may choose to use only a file logger and a tty logger.
33 | **/
34 |
35 | #import "DDLog.h"
36 |
37 | #define LOG_CONTEXT_ALL INT_MAX
38 |
39 | #if TARGET_OS_IPHONE
40 | // iOS
41 | #import
42 | #define DDColor UIColor
43 | #define DDMakeColor(r, g, b) [UIColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f]
44 | #elif __has_include()
45 | // OS X with AppKit
46 | #import
47 | #define DDColor NSColor
48 | #define DDMakeColor(r, g, b) [NSColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f]
49 | #else
50 | // OS X CLI
51 | #import "CLIColor.h"
52 | #define DDColor CLIColor
53 | #define DDMakeColor(r, g, b) [CLIColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f]
54 | #endif
55 |
56 | @interface DDTTYLogger : DDAbstractLogger
57 |
58 | + (instancetype)sharedInstance;
59 |
60 | /* Inherited from the DDLogger protocol:
61 | *
62 | * Formatters may optionally be added to any logger.
63 | *
64 | * If no formatter is set, the logger simply logs the message as it is given in logMessage,
65 | * or it may use its own built in formatting style.
66 | *
67 | * More information about formatters can be found here:
68 | * Documentation/CustomFormatters.md
69 | *
70 | * The actual implementation of these methods is inherited from DDAbstractLogger.
71 |
72 | - (id )logFormatter;
73 | - (void)setLogFormatter:(id )formatter;
74 |
75 | */
76 |
77 | /**
78 | * Want to use different colors for different log levels?
79 | * Enable this property.
80 | *
81 | * If you run the application via the Terminal (not Xcode),
82 | * the logger will map colors to xterm-256color or xterm-color (if available).
83 | *
84 | * Xcode does NOT natively support colors in the Xcode debugging console.
85 | * You'll need to install the XcodeColors plugin to see colors in the Xcode console.
86 | * https://github.com/robbiehanson/XcodeColors
87 | *
88 | * The default value is NO.
89 | **/
90 | @property (readwrite, assign) BOOL colorsEnabled;
91 |
92 | /**
93 | * When using a custom formatter you can set the logMessage method not to append
94 | * '\n' character after each output. This allows for some greater flexibility with
95 | * custom formatters. Default value is YES.
96 | **/
97 |
98 | @property (readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
99 |
100 | /**
101 | * The default color set (foregroundColor, backgroundColor) is:
102 | *
103 | * - LOG_FLAG_ERROR = (red, nil)
104 | * - LOG_FLAG_WARN = (orange, nil)
105 | *
106 | * You can customize the colors however you see fit.
107 | * Please note that you are passing a flag, NOT a level.
108 | *
109 | * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
110 | * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
111 | *
112 | * LOG_FLAG_INFO = 0...00100
113 | * LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR
114 | *
115 | * If you run the application within Xcode, then the XcodeColors plugin is required.
116 | *
117 | * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
118 | * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
119 | *
120 | * This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
121 | **/
122 | - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(int)mask;
123 |
124 | /**
125 | * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
126 | *
127 | * A logging context is often used to identify log messages coming from a 3rd party framework,
128 | * although logging context's can be used for many different functions.
129 | *
130 | * Use LOG_CONTEXT_ALL to set the deafult color for all contexts that have no specific color set defined.
131 | *
132 | * Logging context's are explained in further detail here:
133 | * Documentation/CustomContext.md
134 | **/
135 | - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(int)mask context:(int)ctxt;
136 |
137 | /**
138 | * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
139 | * For example, you could do something like this:
140 | *
141 | * static NSString *const PurpleTag = @"PurpleTag";
142 | *
143 | * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
144 | *
145 | * And then where you configure CocoaLumberjack:
146 | *
147 | * purple = DDMakeColor((64/255.0), (0/255.0), (128/255.0));
148 | *
149 | * or any UIColor/NSColor constructor.
150 | *
151 | * Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
152 | *
153 | * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
154 | * [DDLog addLogger:[DDTTYLogger sharedInstance]];
155 | *
156 | * This would essentially give you a straight NSLog replacement that prints in purple:
157 | *
158 | * DDLogPurple(@"I'm a purple log message!");
159 | **/
160 | - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id )tag;
161 |
162 | /**
163 | * Clearing color profiles.
164 | **/
165 | - (void)clearColorsForFlag:(int)mask;
166 | - (void)clearColorsForFlag:(int)mask context:(int)context;
167 | - (void)clearColorsForTag:(id )tag;
168 | - (void)clearColorsForAllFlags;
169 | - (void)clearColorsForAllTags;
170 | - (void)clearAllColors;
171 |
172 | @end
173 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDContextFilterLogFormatter.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import
17 | #import "DDLog.h"
18 |
19 | /**
20 | * This class provides a log formatter that filters log statements from a logging context not on the whitelist.
21 | *
22 | * A log formatter can be added to any logger to format and/or filter its output.
23 | * You can learn more about log formatters here:
24 | * Documentation/CustomFormatters.md
25 | *
26 | * You can learn more about logging context's here:
27 | * Documentation/CustomContext.md
28 | *
29 | * But here's a quick overview / refresher:
30 | *
31 | * Every log statement has a logging context.
32 | * These come from the underlying logging macros defined in DDLog.h.
33 | * The default logging context is zero.
34 | * You can define multiple logging context's for use in your application.
35 | * For example, logically separate parts of your app each have a different logging context.
36 | * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
37 | **/
38 | @interface DDContextWhitelistFilterLogFormatter : NSObject
39 |
40 | - (id)init;
41 |
42 | - (void)addToWhitelist:(int)loggingContext;
43 | - (void)removeFromWhitelist:(int)loggingContext;
44 |
45 | - (NSArray *)whitelist;
46 |
47 | - (BOOL)isOnWhitelist:(int)loggingContext;
48 |
49 | @end
50 |
51 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
52 | #pragma mark -
53 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54 |
55 | /**
56 | * This class provides a log formatter that filters log statements from a logging context on the blacklist.
57 | **/
58 | @interface DDContextBlacklistFilterLogFormatter : NSObject
59 |
60 | - (id)init;
61 |
62 | - (void)addToBlacklist:(int)loggingContext;
63 | - (void)removeFromBlacklist:(int)loggingContext;
64 |
65 | - (NSArray *)blacklist;
66 |
67 | - (BOOL)isOnBlacklist:(int)loggingContext;
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDContextFilterLogFormatter.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDContextFilterLogFormatter.h"
17 | #import
18 |
19 | #if !__has_feature(objc_arc)
20 | #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
21 | #endif
22 |
23 | @interface DDLoggingContextSet : NSObject
24 |
25 | - (void)addToSet:(int)loggingContext;
26 | - (void)removeFromSet:(int)loggingContext;
27 |
28 | - (NSArray *)currentSet;
29 |
30 | - (BOOL)isInSet:(int)loggingContext;
31 |
32 | @end
33 |
34 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35 | #pragma mark -
36 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
37 |
38 | @interface DDContextWhitelistFilterLogFormatter () {
39 | DDLoggingContextSet *_contextSet;
40 | }
41 |
42 | @end
43 |
44 |
45 | @implementation DDContextWhitelistFilterLogFormatter
46 |
47 | - (id)init {
48 | if ((self = [super init])) {
49 | _contextSet = [[DDLoggingContextSet alloc] init];
50 | }
51 |
52 | return self;
53 | }
54 |
55 | - (void)addToWhitelist:(int)loggingContext {
56 | [_contextSet addToSet:loggingContext];
57 | }
58 |
59 | - (void)removeFromWhitelist:(int)loggingContext {
60 | [_contextSet removeFromSet:loggingContext];
61 | }
62 |
63 | - (NSArray *)whitelist {
64 | return [_contextSet currentSet];
65 | }
66 |
67 | - (BOOL)isOnWhitelist:(int)loggingContext {
68 | return [_contextSet isInSet:loggingContext];
69 | }
70 |
71 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
72 | if ([self isOnWhitelist:logMessage->logContext]) {
73 | return logMessage->logMsg;
74 | } else {
75 | return nil;
76 | }
77 | }
78 |
79 | @end
80 |
81 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82 | #pragma mark -
83 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
84 |
85 | @interface DDContextBlacklistFilterLogFormatter () {
86 | DDLoggingContextSet *_contextSet;
87 | }
88 |
89 | @end
90 |
91 |
92 | @implementation DDContextBlacklistFilterLogFormatter
93 |
94 | - (id)init {
95 | if ((self = [super init])) {
96 | _contextSet = [[DDLoggingContextSet alloc] init];
97 | }
98 |
99 | return self;
100 | }
101 |
102 | - (void)addToBlacklist:(int)loggingContext {
103 | [_contextSet addToSet:loggingContext];
104 | }
105 |
106 | - (void)removeFromBlacklist:(int)loggingContext {
107 | [_contextSet removeFromSet:loggingContext];
108 | }
109 |
110 | - (NSArray *)blacklist {
111 | return [_contextSet currentSet];
112 | }
113 |
114 | - (BOOL)isOnBlacklist:(int)loggingContext {
115 | return [_contextSet isInSet:loggingContext];
116 | }
117 |
118 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
119 | if ([self isOnBlacklist:logMessage->logContext]) {
120 | return nil;
121 | } else {
122 | return logMessage->logMsg;
123 | }
124 | }
125 |
126 | @end
127 |
128 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
129 | #pragma mark -
130 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131 |
132 |
133 | @interface DDLoggingContextSet () {
134 | OSSpinLock _lock;
135 | NSMutableSet *_set;
136 | }
137 |
138 | @end
139 |
140 |
141 | @implementation DDLoggingContextSet
142 |
143 | - (id)init {
144 | if ((self = [super init])) {
145 | _set = [[NSMutableSet alloc] init];
146 | }
147 |
148 | return self;
149 | }
150 |
151 | - (void)addToSet:(int)loggingContext {
152 | OSSpinLockLock(&_lock);
153 | {
154 | [_set addObject:@(loggingContext)];
155 | }
156 | OSSpinLockUnlock(&_lock);
157 | }
158 |
159 | - (void)removeFromSet:(int)loggingContext {
160 | OSSpinLockLock(&_lock);
161 | {
162 | [_set removeObject:@(loggingContext)];
163 | }
164 | OSSpinLockUnlock(&_lock);
165 | }
166 |
167 | - (NSArray *)currentSet {
168 | NSArray *result = nil;
169 |
170 | OSSpinLockLock(&_lock);
171 | {
172 | result = [_set allObjects];
173 | }
174 | OSSpinLockUnlock(&_lock);
175 |
176 | return result;
177 | }
178 |
179 | - (BOOL)isInSet:(int)loggingContext {
180 | BOOL result = NO;
181 |
182 | OSSpinLockLock(&_lock);
183 | {
184 | result = [_set containsObject:@(loggingContext)];
185 | }
186 | OSSpinLockUnlock(&_lock);
187 |
188 | return result;
189 | }
190 |
191 | @end
192 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDDispatchQueueLogFormatter.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import
17 | #import
18 | #import "DDLog.h"
19 |
20 |
21 | /**
22 | * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id.
23 | *
24 | * A log formatter can be added to any logger to format and/or filter its output.
25 | * You can learn more about log formatters here:
26 | * Documentation/CustomFormatters.md
27 | *
28 | * A typical NSLog (or DDTTYLogger) prints detailed info as [:].
29 | * For example:
30 | *
31 | * 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here
32 | *
33 | * Where:
34 | * - 19928 = process id
35 | * - 5207 = thread id (mach_thread_id printed in hex)
36 | *
37 | * When using grand central dispatch (GCD), this information is less useful.
38 | * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool.
39 | * For example:
40 | *
41 | * 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue
42 | * 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue
43 | * 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue
44 | *
45 | * This formatter allows you to replace the standard [box:info] with the dispatch_queue name.
46 | * For example:
47 | *
48 | * 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue
49 | * 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue
50 | * 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue
51 | *
52 | * If the dispatch_queue doesn't have a set name, then it falls back to the thread name.
53 | * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal).
54 | *
55 | * Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread),
56 | * you can use [[NSThread currentThread] setName:(NSString *)].
57 | **/
58 | @interface DDDispatchQueueLogFormatter : NSObject
59 |
60 | /**
61 | * Standard init method.
62 | * Configure using properties as desired.
63 | **/
64 | - (id)init;
65 |
66 | /**
67 | * The minQueueLength restricts the minimum size of the [detail box].
68 | * If the minQueueLength is set to 0, there is no restriction.
69 | *
70 | * For example, say a dispatch_queue has a label of "diskIO":
71 | *
72 | * If the minQueueLength is 0: [diskIO]
73 | * If the minQueueLength is 4: [diskIO]
74 | * If the minQueueLength is 5: [diskIO]
75 | * If the minQueueLength is 6: [diskIO]
76 | * If the minQueueLength is 7: [diskIO ]
77 | * If the minQueueLength is 8: [diskIO ]
78 | *
79 | * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded).
80 | *
81 | * If you want every [detail box] to have the exact same width,
82 | * set both minQueueLength and maxQueueLength to the same value.
83 | **/
84 | @property (assign, atomic) NSUInteger minQueueLength;
85 |
86 | /**
87 | * The maxQueueLength restricts the number of characters that will be inside the [detail box].
88 | * If the maxQueueLength is 0, there is no restriction.
89 | *
90 | * For example, say a dispatch_queue has a label of "diskIO":
91 | *
92 | * If the maxQueueLength is 0: [diskIO]
93 | * If the maxQueueLength is 4: [disk]
94 | * If the maxQueueLength is 5: [diskI]
95 | * If the maxQueueLength is 6: [diskIO]
96 | * If the maxQueueLength is 7: [diskIO]
97 | * If the maxQueueLength is 8: [diskIO]
98 | *
99 | * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated).
100 | *
101 | * If you want every [detail box] to have the exact same width,
102 | * set both minQueueLength and maxQueueLength to the same value.
103 | **/
104 | @property (assign, atomic) NSUInteger maxQueueLength;
105 |
106 | /**
107 | * Sometimes queue labels have long names like "com.apple.main-queue",
108 | * but you'd prefer something shorter like simply "main".
109 | *
110 | * This method allows you to set such preferred replacements.
111 | * The above example is set by default.
112 | *
113 | * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter.
114 | **/
115 | - (NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
116 | - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
117 |
118 | @end
119 |
120 | /**
121 | * Method declarations that make it easier to extend/modify DDDispatchQueueLogFormatter
122 | **/
123 | @interface DDDispatchQueueLogFormatter (OverridableMethods)
124 |
125 | - (NSString *)stringFromDate:(NSDate *)date;
126 | - (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage;
127 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDDispatchQueueLogFormatter.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDDispatchQueueLogFormatter.h"
17 | #import
18 |
19 |
20 | #if !__has_feature(objc_arc)
21 | #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
22 | #endif
23 |
24 | @interface DDDispatchQueueLogFormatter () {
25 | NSString *_dateFormatString;
26 |
27 | int32_t _atomicLoggerCount;
28 | NSDateFormatter *_threadUnsafeDateFormatter; // Use [self stringFromDate]
29 |
30 | OSSpinLock _lock;
31 |
32 | NSUInteger _minQueueLength; // _prefix == Only access via atomic property
33 | NSUInteger _maxQueueLength; // _prefix == Only access via atomic property
34 | NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock
35 | }
36 |
37 | @end
38 |
39 |
40 | @implementation DDDispatchQueueLogFormatter
41 |
42 | - (id)init {
43 | if ((self = [super init])) {
44 | _dateFormatString = @"yyyy-MM-dd HH:mm:ss:SSS";
45 |
46 | _atomicLoggerCount = 0;
47 | _threadUnsafeDateFormatter = nil;
48 |
49 | _minQueueLength = 0;
50 | _maxQueueLength = 0;
51 | _replacements = [[NSMutableDictionary alloc] init];
52 |
53 | // Set default replacements:
54 |
55 | _replacements[@"com.apple.main-thread"] = @"main";
56 | }
57 |
58 | return self;
59 | }
60 |
61 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
62 | #pragma mark Configuration
63 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
64 |
65 | @synthesize minQueueLength = _minQueueLength;
66 | @synthesize maxQueueLength = _maxQueueLength;
67 |
68 | - (NSString *)replacementStringForQueueLabel:(NSString *)longLabel {
69 | NSString *result = nil;
70 |
71 | OSSpinLockLock(&_lock);
72 | {
73 | result = _replacements[longLabel];
74 | }
75 | OSSpinLockUnlock(&_lock);
76 |
77 | return result;
78 | }
79 |
80 | - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel {
81 | OSSpinLockLock(&_lock);
82 | {
83 | if (shortLabel) {
84 | _replacements[longLabel] = shortLabel;
85 | } else {
86 | [_replacements removeObjectForKey:longLabel];
87 | }
88 | }
89 | OSSpinLockUnlock(&_lock);
90 | }
91 |
92 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93 | #pragma mark DDLogFormatter
94 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
95 |
96 | - (NSString *)stringFromDate:(NSDate *)date {
97 | int32_t loggerCount = OSAtomicAdd32(0, &_atomicLoggerCount);
98 |
99 | NSString *calendarIdentifier = nil;
100 |
101 | #if defined(__IPHONE_8_0) || defined(__MAC_10_10)
102 | calendarIdentifier = NSCalendarIdentifierGregorian;
103 | #else
104 | calendarIdentifier = NSGregorianCalendar;
105 | #endif
106 |
107 | if (loggerCount <= 1) {
108 | // Single-threaded mode.
109 |
110 | if (_threadUnsafeDateFormatter == nil) {
111 | _threadUnsafeDateFormatter = [[NSDateFormatter alloc] init];
112 | [_threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
113 | [_threadUnsafeDateFormatter setDateFormat:_dateFormatString];
114 | }
115 |
116 | [_threadUnsafeDateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]];
117 | return [_threadUnsafeDateFormatter stringFromDate:date];
118 | } else {
119 | // Multi-threaded mode.
120 | // NSDateFormatter is NOT thread-safe.
121 |
122 | NSString *key = @"DispatchQueueLogFormatter_NSDateFormatter";
123 |
124 | NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
125 | NSDateFormatter *dateFormatter = threadDictionary[key];
126 |
127 | if (dateFormatter == nil) {
128 | dateFormatter = [[NSDateFormatter alloc] init];
129 | [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
130 | [dateFormatter setDateFormat:_dateFormatString];
131 |
132 | threadDictionary[key] = dateFormatter;
133 | }
134 |
135 | [dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]];
136 | return [dateFormatter stringFromDate:date];
137 | }
138 | }
139 |
140 | - (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage {
141 | // As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue
142 |
143 | NSUInteger minQueueLength = self.minQueueLength;
144 | NSUInteger maxQueueLength = self.maxQueueLength;
145 |
146 | // Get the name of the queue, thread, or machID (whichever we are to use).
147 |
148 | NSString *queueThreadLabel = nil;
149 |
150 | BOOL useQueueLabel = YES;
151 | BOOL useThreadName = NO;
152 |
153 | if (logMessage->queueLabel) {
154 | // If you manually create a thread, it's dispatch_queue will have one of the thread names below.
155 | // Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID.
156 |
157 | char *names[] = {
158 | "com.apple.root.low-priority",
159 | "com.apple.root.default-priority",
160 | "com.apple.root.high-priority",
161 | "com.apple.root.low-overcommit-priority",
162 | "com.apple.root.default-overcommit-priority",
163 | "com.apple.root.high-overcommit-priority"
164 | };
165 |
166 | int length = sizeof(names) / sizeof(char *);
167 |
168 | int i;
169 |
170 | for (i = 0; i < length; i++) {
171 | if (strcmp(logMessage->queueLabel, names[i]) == 0) {
172 | useQueueLabel = NO;
173 | useThreadName = [logMessage->threadName length] > 0;
174 | break;
175 | }
176 | }
177 | } else {
178 | useQueueLabel = NO;
179 | useThreadName = [logMessage->threadName length] > 0;
180 | }
181 |
182 | if (useQueueLabel || useThreadName) {
183 | NSString *fullLabel;
184 | NSString *abrvLabel;
185 |
186 | if (useQueueLabel) {
187 | fullLabel = @(logMessage->queueLabel);
188 | } else {
189 | fullLabel = logMessage->threadName;
190 | }
191 |
192 | OSSpinLockLock(&_lock);
193 | {
194 | abrvLabel = _replacements[fullLabel];
195 | }
196 | OSSpinLockUnlock(&_lock);
197 |
198 | if (abrvLabel) {
199 | queueThreadLabel = abrvLabel;
200 | } else {
201 | queueThreadLabel = fullLabel;
202 | }
203 | } else {
204 | queueThreadLabel = [NSString stringWithFormat:@"%x", logMessage->machThreadID];
205 | }
206 |
207 | // Now use the thread label in the output
208 |
209 | NSUInteger labelLength = [queueThreadLabel length];
210 |
211 | // labelLength > maxQueueLength : truncate
212 | // labelLength < minQueueLength : padding
213 | // : exact
214 |
215 | if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) {
216 | // Truncate
217 |
218 | return [queueThreadLabel substringToIndex:maxQueueLength];
219 | } else if (labelLength < minQueueLength) {
220 | // Padding
221 |
222 | NSUInteger numSpaces = minQueueLength - labelLength;
223 |
224 | char spaces[numSpaces + 1];
225 | memset(spaces, ' ', numSpaces);
226 | spaces[numSpaces] = '\0';
227 |
228 | return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces];
229 | } else {
230 | // Exact
231 |
232 | return queueThreadLabel;
233 | }
234 | }
235 |
236 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
237 | NSString *timestamp = [self stringFromDate:(logMessage->timestamp)];
238 | NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage];
239 |
240 | return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, queueThreadLabel, logMessage->logMsg];
241 | }
242 |
243 | - (void)didAddToLogger:(id )logger {
244 | OSAtomicIncrement32(&_atomicLoggerCount);
245 | }
246 |
247 | - (void)willRemoveFromLogger:(id )logger {
248 | OSAtomicDecrement32(&_atomicLoggerCount);
249 | }
250 |
251 | @end
252 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDMultiFormatter.h:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import
17 | #import "DDLog.h"
18 |
19 | /**
20 | * This formatter can be used to chain different formatters together.
21 | * The log message will processed in the order of the formatters added.
22 | **/
23 |
24 | @interface DDMultiFormatter : NSObject
25 |
26 | /**
27 | * Array of chained formatters
28 | */
29 | @property (readonly) NSArray *formatters;
30 |
31 | - (void)addFormatter:(id)formatter;
32 | - (void)removeFormatter:(id)formatter;
33 | - (void)removeAllFormatters;
34 | - (BOOL)isFormattingWithFormatter:(id)formatter;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/Classes/Extensions/DDMultiFormatter.m:
--------------------------------------------------------------------------------
1 | // Software License Agreement (BSD License)
2 | //
3 | // Copyright (c) 2010-2014, Deusty, LLC
4 | // All rights reserved.
5 | //
6 | // Redistribution and use of this software in source and binary forms,
7 | // with or without modification, are permitted provided that the following conditions are met:
8 | //
9 | // * Redistributions of source code must retain the above copyright notice,
10 | // this list of conditions and the following disclaimer.
11 | //
12 | // * Neither the name of Deusty nor the names of its contributors may be used
13 | // to endorse or promote products derived from this software without specific
14 | // prior written permission of Deusty, LLC.
15 |
16 | #import "DDMultiFormatter.h"
17 |
18 |
19 | #if TARGET_OS_IPHONE
20 | // Compiling for iOS
21 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 // iOS 6.0 or later
22 | #define NEEDS_DISPATCH_RETAIN_RELEASE 0
23 | #else // iOS 5.X or earlier
24 | #define NEEDS_DISPATCH_RETAIN_RELEASE 1
25 | #endif
26 | #else
27 | // Compiling for Mac OS X
28 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 // Mac OS X 10.8 or later
29 | #define NEEDS_DISPATCH_RETAIN_RELEASE 0
30 | #else // Mac OS X 10.7 or earlier
31 | #define NEEDS_DISPATCH_RETAIN_RELEASE 1
32 | #endif
33 | #endif
34 |
35 |
36 | #if !__has_feature(objc_arc)
37 | #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
38 | #endif
39 |
40 |
41 | @interface DDMultiFormatter () {
42 | dispatch_queue_t _queue;
43 | NSMutableArray *_formatters;
44 | }
45 |
46 | - (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message;
47 |
48 | @end
49 |
50 |
51 | @implementation DDMultiFormatter
52 |
53 | - (id)init {
54 | self = [super init];
55 |
56 | if (self) {
57 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
58 | _queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", DISPATCH_QUEUE_CONCURRENT);
59 | #else
60 | _queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", NULL);
61 | #endif
62 | _formatters = [NSMutableArray new];
63 | }
64 |
65 | return self;
66 | }
67 |
68 | #if NEEDS_DISPATCH_RETAIN_RELEASE
69 | - (void)dealloc {
70 | dispatch_release(_queue);
71 | }
72 |
73 | #endif
74 |
75 | #pragma mark Processing
76 |
77 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
78 | __block NSString *line = logMessage->logMsg;
79 |
80 | dispatch_sync(_queue, ^{
81 | for (id formatter in _formatters) {
82 | DDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage];
83 | line = [formatter formatLogMessage:message];
84 |
85 | if (!line) {
86 | break;
87 | }
88 | }
89 | });
90 |
91 | return line;
92 | }
93 |
94 | - (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message {
95 | DDLogMessage *newMessage = [message copy];
96 |
97 | newMessage->logMsg = line;
98 | return newMessage;
99 | }
100 |
101 | #pragma mark Formatters
102 |
103 | - (NSArray *)formatters {
104 | __block NSArray *formatters;
105 |
106 | dispatch_sync(_queue, ^{
107 | formatters = [_formatters copy];
108 | });
109 |
110 | return formatters;
111 | }
112 |
113 | - (void)addFormatter:(id)formatter {
114 | dispatch_barrier_async(_queue, ^{
115 | [_formatters addObject:formatter];
116 | });
117 | }
118 |
119 | - (void)removeFormatter:(id)formatter {
120 | dispatch_barrier_async(_queue, ^{
121 | [_formatters removeObject:formatter];
122 | });
123 | }
124 |
125 | - (void)removeAllFormatters {
126 | dispatch_barrier_async(_queue, ^{
127 | [_formatters removeAllObjects];
128 | });
129 | }
130 |
131 | - (BOOL)isFormattingWithFormatter:(id)formatter {
132 | __block BOOL hasFormatter;
133 |
134 | dispatch_sync(_queue, ^{
135 | hasFormatter = [_formatters containsObject:formatter];
136 | });
137 |
138 | return hasFormatter;
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Software License Agreement (BSD License)
2 |
3 | Copyright (c) 2010-2014, Deusty, LLC
4 | All rights reserved.
5 |
6 | Redistribution and use of this software in source and binary forms,
7 | with or without modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above
10 | copyright notice, this list of conditions and the
11 | following disclaimer.
12 |
13 | * Neither the name of Deusty nor the names of its
14 | contributors may be used to endorse or promote products
15 | derived from this software without specific prior
16 | written permission of Deusty, LLC.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/Pods/CocoaLumberjack/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CocoaLumberjack
6 | ===============
7 | [](https://travis-ci.org/CocoaLumberjack/CocoaLumberjack)
8 | [](http://cocoadocs.org/docsets/CocoaLumberjack/)
9 | [](http://cocoadocs.org/docsets/CocoaLumberjack/)
10 | [](http://opensource.org/licenses/BSD-3-Clause)
11 | [](https://www.versioneye.com/objective-c/cocoalumberjack/references)
12 |
13 | **CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for Mac and iOS.
14 |
15 | ### CocoaLumberjack 2 pre-release notes
16 |
17 | #### Migrating to 2.x-beta
18 |
19 | * Replace `DDLog.h` imports by `#import `.
20 | * Replace all `DDLogC` macros for regular `DDLog` macros.
21 |
22 | #### Forcing 1.x
23 |
24 | If an included library requires it, you can force CocoaLumberjack 1.x by setting the version before the conflicting library:
25 |
26 | ```ruby
27 | pod 'CocoaLumberjack', '~> 1.9'
28 | pod 'ConflictingLibrary'
29 | ```
30 |
31 | ### Features
32 |
33 | #### Lumberjack is Fast & Simple, yet Powerful & Flexible.
34 |
35 | It is similar in concept to other popular logging frameworks such as log4j, yet is designed specifically for Objective-C, and takes advantage of features such as multi-threading, grand central dispatch (if available), lockless atomic operations, and the dynamic nature of the Objective-C runtime.
36 |
37 | #### Lumberjack is Fast
38 |
39 | In most cases it is an order of magnitude faster than NSLog.
40 |
41 | #### Lumberjack is Simple
42 |
43 | It takes as little as a single line of code to configure lumberjack when your application launches. Then simply replace your NSLog statements with DDLog statements and that's about it. (And the DDLog macros have the exact same format and syntax as NSLog, so it's super easy.)
44 |
45 | #### Lumberjack is Powerful:
46 |
47 | One log statement can be sent to multiple loggers, meaning you can log to a file and the console simultaneously. Want more? Create your own loggers (it's easy) and send your log statements over the network. Or to a database or distributed file system. The sky is the limit.
48 |
49 | #### Lumberjack is Flexible:
50 |
51 | Configure your logging however you want. Change log levels per file (perfect for debugging). Change log levels per logger (verbose console, but concise log file). Change log levels per xcode configuration (verbose debug, but concise release). Have your log statements compiled out of the release build. Customize the number of log levels for your application. Add your own fine-grained logging. Dynamically change log levels during runtime. Choose how & when you want your log files to be rolled. Upload your log files to a central server. Compress archived log files to save disk space...
52 |
53 | ### This framework is for you if:
54 |
55 | - You're looking for a way to track down that impossible-to-reproduce bug that keeps popping up in the field.
56 | - You're frustrated with the super short console log on the iPhone.
57 | - You're looking to take your application to the next level in terms of support and stability.
58 | - You're looking for an enterprise level logging solution for your application (Mac or iPhone).
59 |
60 | ### How to get started
61 | - install via [CocoaPods](http://cocoapods.org)
62 |
63 | ```ruby
64 | platform :ios, '6.1'
65 | pod 'CocoaLumberjack'
66 | ```
67 | - read the [Getting started](Documentation/GettingStarted.md) guide, check out the [FAQ](Documentation/FAQ.md) section or the other [docs](Documentation/)
68 | - if you find issues or want to suggest improvements, create an issue or a pull request
69 | - for all kinds of questions involving CocoaLumberjack, use the [Google group](http://groups.google.com/group/cocoalumberjack) or StackOverflow (use [#lumberjack](http://stackoverflow.com/questions/tagged/lumberjack)).
70 |
71 | ### Documentation
72 |
73 | - **[Get started using Lumberjack](Documentation/GettingStarted.md)**
74 | - [Different log levels for Debug and Release builds](Documentation/XcodeTricks.md)
75 | - [Different log levels for each logger](Documentation/PerLoggerLogLevels.md)
76 | - [Use colors in the Xcode debugging console](Documentation/XcodeColors.md)
77 | - [Write your own custom formatters](Documentation/CustomFormatters.md)
78 | - [FAQ](Documentation/FAQ.md)
79 | - [Analysis of performance with benchmarks](Documentation/Performance.md)
80 | - [Common issues you may encounter and their solutions](Documentation/ProblemSolution.md)
81 | - [AppCode support](Documentation/AppCode-support.md)
82 | - **[Full Lumberjack documentation](Documentation/)**
83 |
84 | ### Requirements
85 | - Xcode 4.4 or later is required
86 | - iOS 5 or later
87 | - OS X 10.7 or later
88 | - for OS X < 10.7 support, use the 1.6.0 version
89 |
90 | ### Author
91 | - [Robbie Hanson](https://github.com/robbiehanson)
92 | - Love the project? Wanna buy me a coffee? (or a beer :D) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA)
93 |
94 | ### Collaborators
95 | - [Ernesto Rivera](https://github.com/rivera-ernesto)
96 | - [Dmitry Vorobyov](https://github.com/dvor)
97 | - [Bogdan Poplauschi](https://github.com/bpoplauschi)
98 |
99 | ### License
100 | - CocoaLumberjack is available under the BSD license. See the [LICENSE file](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/LICENSE.txt).
101 |
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Crashlytics:
--------------------------------------------------------------------------------
1 | Versions/Current/Crashlytics
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Headers:
--------------------------------------------------------------------------------
1 | Versions/Current/Headers
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module Crashlytics {
2 | umbrella header "Crashlytics.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Resources:
--------------------------------------------------------------------------------
1 | Versions/Current/Resources
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Versions/A/Crashlytics:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/Pods/CrashlyticsFramework/Crashlytics.framework/Versions/A/Crashlytics
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Versions/A/Headers/Crashlytics.h:
--------------------------------------------------------------------------------
1 | //
2 | // Crashlytics.h
3 | // Crashlytics
4 | //
5 | // Copyright 2013 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | /**
11 | *
12 | * The CLS_LOG macro provides as easy way to gather more information in your log messages that are
13 | * sent with your crash data. CLS_LOG prepends your custom log message with the function name and
14 | * line number where the macro was used. If your app was built with the DEBUG preprocessor macro
15 | * defined CLS_LOG uses the CLSNSLog function which forwards your log message to NSLog and CLSLog.
16 | * If the DEBUG preprocessor macro is not defined CLS_LOG uses CLSLog only.
17 | *
18 | * Example output:
19 | * -[AppDelegate login:] line 134 $ login start
20 | *
21 | * If you would like to change this macro, create a new header file, unset our define and then define
22 | * your own version. Make sure this new header file is imported after the Crashlytics header file.
23 | *
24 | * #undef CLS_LOG
25 | * #define CLS_LOG(__FORMAT__, ...) CLSNSLog...
26 | *
27 | **/
28 | #ifdef DEBUG
29 | #define CLS_LOG(__FORMAT__, ...) CLSNSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
30 | #else
31 | #define CLS_LOG(__FORMAT__, ...) CLSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
32 | #endif
33 |
34 | /**
35 | *
36 | * Add logging that will be sent with your crash data. This logging will not show up in the system.log
37 | * and will only be visible in your Crashlytics dashboard.
38 | *
39 | **/
40 | OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
41 | OBJC_EXTERN void CLSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
42 |
43 | /**
44 | *
45 | * Add logging that will be sent with your crash data. This logging will show up in the system.log
46 | * and your Crashlytics dashboard. It is not recommended for Release builds.
47 | *
48 | **/
49 | OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
50 | OBJC_EXTERN void CLSNSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
51 |
52 |
53 | @protocol CrashlyticsDelegate;
54 |
55 | @interface Crashlytics : NSObject
56 |
57 | @property (nonatomic, readonly, copy) NSString *apiKey;
58 | @property (nonatomic, readonly, copy) NSString *version;
59 | @property (nonatomic, assign) BOOL debugMode;
60 |
61 | @property (nonatomic, assign) NSObject *delegate;
62 |
63 | /**
64 | *
65 | * The recommended way to install Crashlytics into your application is to place a call
66 | * to +startWithAPIKey: in your -application:didFinishLaunchingWithOptions: method.
67 | *
68 | * This delay defaults to 1 second in order to generally give the application time to
69 | * fully finish launching.
70 | *
71 | **/
72 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey;
73 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey afterDelay:(NSTimeInterval)delay;
74 |
75 | /**
76 | *
77 | * If you need the functionality provided by the CrashlyticsDelegate protocol, you can use
78 | * these convenience methods to activate the framework and set the delegate in one call.
79 | *
80 | **/
81 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(NSObject *)delegate;
82 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(NSObject *)delegate afterDelay:(NSTimeInterval)delay;
83 |
84 | /**
85 | *
86 | * Access the singleton Crashlytics instance.
87 | *
88 | **/
89 | + (Crashlytics *)sharedInstance;
90 |
91 | /**
92 | *
93 | * The easiest way to cause a crash - great for testing!
94 | *
95 | **/
96 | - (void)crash;
97 |
98 | /**
99 | *
100 | * Many of our customers have requested the ability to tie crashes to specific end-users of their
101 | * application in order to facilitate responses to support requests or permit the ability to reach
102 | * out for more information. We allow you to specify up to three separate values for display within
103 | * the Crashlytics UI - but please be mindful of your end-user's privacy.
104 | *
105 | * We recommend specifying a user identifier - an arbitrary string that ties an end-user to a record
106 | * in your system. This could be a database id, hash, or other value that is meaningless to a
107 | * third-party observer but can be indexed and queried by you.
108 | *
109 | * Optionally, you may also specify the end-user's name or username, as well as email address if you
110 | * do not have a system that works well with obscured identifiers.
111 | *
112 | * Pursuant to our EULA, this data is transferred securely throughout our system and we will not
113 | * disseminate end-user data unless required to by law. That said, if you choose to provide end-user
114 | * contact information, we strongly recommend that you disclose this in your application's privacy
115 | * policy. Data privacy is of our utmost concern.
116 | *
117 | **/
118 | - (void)setUserIdentifier:(NSString *)identifier;
119 | - (void)setUserName:(NSString *)name;
120 | - (void)setUserEmail:(NSString *)email;
121 |
122 | + (void)setUserIdentifier:(NSString *)identifier;
123 | + (void)setUserName:(NSString *)name;
124 | + (void)setUserEmail:(NSString *)email;
125 |
126 | /**
127 | *
128 | * Set a value for a key to be associated with your crash data.
129 | *
130 | **/
131 | - (void)setObjectValue:(id)value forKey:(NSString *)key;
132 | - (void)setIntValue:(int)value forKey:(NSString *)key;
133 | - (void)setBoolValue:(BOOL)value forKey:(NSString *)key;
134 | - (void)setFloatValue:(float)value forKey:(NSString *)key;
135 |
136 | + (void)setObjectValue:(id)value forKey:(NSString *)key;
137 | + (void)setIntValue:(int)value forKey:(NSString *)key;
138 | + (void)setBoolValue:(BOOL)value forKey:(NSString *)key;
139 | + (void)setFloatValue:(float)value forKey:(NSString *)key;
140 |
141 | @end
142 |
143 | /**
144 | * The CLSCrashReport protocol exposes methods that you can call on crash report objects passed
145 | * to delegate methods. If you want these values or the entire object to stay in memory retain
146 | * them or copy them.
147 | **/
148 | @protocol CLSCrashReport
149 | @required
150 |
151 | /**
152 | * Returns the session identifier for the crash report.
153 | **/
154 | @property (nonatomic, readonly) NSString *identifier;
155 |
156 | /**
157 | * Returns the custom key value data for the crash report.
158 | **/
159 | @property (nonatomic, readonly) NSDictionary *customKeys;
160 |
161 | /**
162 | * Returns the CFBundleVersion of the application that crashed.
163 | **/
164 | @property (nonatomic, readonly) NSString *bundleVersion;
165 |
166 | /**
167 | * Returns the CFBundleShortVersionString of the application that crashed.
168 | **/
169 | @property (nonatomic, readonly) NSString *bundleShortVersionString;
170 |
171 | /**
172 | * Returns the date that the application crashed at.
173 | **/
174 | @property (nonatomic, readonly) NSDate *crashedOnDate;
175 |
176 | /**
177 | * Returns the os version that the application crashed on.
178 | **/
179 | @property (nonatomic, readonly) NSString *OSVersion;
180 |
181 | /**
182 | * Returns the os build version that the application crashed on.
183 | **/
184 | @property (nonatomic, readonly) NSString *OSBuildVersion;
185 |
186 | @end
187 |
188 | /**
189 | *
190 | * The CrashlyticsDelegate protocol provides a mechanism for your application to take
191 | * action on events that occur in the Crashlytics crash reporting system. You can make
192 | * use of these calls by assigning an object to the Crashlytics' delegate property directly,
193 | * or through the convenience startWithAPIKey:delegate:... methods.
194 | *
195 | **/
196 | @protocol CrashlyticsDelegate
197 | @optional
198 |
199 | /**
200 | *
201 | * Called once a Crashlytics instance has determined that the last execution of the
202 | * application ended in a crash. This is called some time after the crash reporting
203 | * process has begun. If you have specified a delay in one of the
204 | * startWithAPIKey:... calls, this will take at least that long to be invoked.
205 | *
206 | **/
207 | - (void)crashlyticsDidDetectCrashDuringPreviousExecution:(Crashlytics *)crashlytics;
208 |
209 | /**
210 | *
211 | * Just like crashlyticsDidDetectCrashDuringPreviousExecution this delegate method is
212 | * called once a Crashlytics instance has determined that the last execution of the
213 | * application ended in a crash. A CLSCrashReport is passed back that contains data about
214 | * the last crash report that was generated. See the CLSCrashReport protocol for method details.
215 | * This method is called after crashlyticsDidDetectCrashDuringPreviousExecution.
216 | *
217 | **/
218 | - (void)crashlytics:(Crashlytics *)crashlytics didDetectCrashDuringPreviousExecution:(id )crash;
219 |
220 | @end
221 |
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Versions/A/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | Crashlytics
9 | CFBundleIdentifier
10 | com.crashlytics.ios
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Crashlytics
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 2.2.5
19 | CFBundleSupportedPlatforms
20 |
21 | iPhoneOS
22 |
23 | CFBundleVersion
24 | 40
25 | DTPlatformName
26 | iphoneos
27 | MinimumOSVersion
28 | 4.0
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/Versions/Current:
--------------------------------------------------------------------------------
1 | A
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/run:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/Pods/CrashlyticsFramework/Crashlytics.framework/run
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/Crashlytics.framework/submit:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/Pods/CrashlyticsFramework/Crashlytics.framework/submit
--------------------------------------------------------------------------------
/Pods/CrashlyticsFramework/README.md:
--------------------------------------------------------------------------------
1 | CrashlyticsFramework
2 | ====================
3 | [](https://travis-ci.org/bpoplauschi/CrashlyticsFramework)
4 | [](http://cocoadocs.org/docsets/CrashlyticsFramework/)
5 | [](http://cocoadocs.org/docsets/CrashlyticsFramework/)
6 | [](http://try.crashlytics.com/terms/terms-of-use.pdf)
7 |
8 | **The most powerful, yet lightest weight crash reporting solution for iOS and Android developers. | Crashlytics**
9 |
10 | ## Reason
11 | *The reason for making this repo was that the Crashlytics framework is not directly available for download anywhere and it's super easy to integrate it via Cocoapods*
12 |
13 | ## Usage via CocoaPods
14 | ``` ruby
15 | pod 'CrashlyticsFramework'
16 | ```
17 |
18 | *Note: the path you should use for the `run` script is `./Pods/CrashlyticsFramework/Crashlytics.framework/run`*
19 |
20 | ## License
21 | - [Crashlytics - Terms of Use](http://try.crashlytics.com/terms/terms-of-service.pdf)
22 | - [Crashlytics - Privacy Policy](http://try.crashlytics.com/terms/privacy-policy.pdf)
23 | - [Crashlytics - Open Source licenses](http://try.crashlytics.com/terms/opensource.txt)
24 |
25 | ## Contact
26 | - [Crashlytics homepage](crashlytics.com)
27 | - [Crashlytics blog](http://www.crashlytics.com/blog/)
28 | - [Crashlytics support](http://support.crashlytics.com/knowledgebase)
29 |
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/CLIColor.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/CLI/CLIColor.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/CocoaLumberjack.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/CocoaLumberjack.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDASLLogCapture.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDASLLogCapture.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDASLLogger.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDASLLogger.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDAbstractDatabaseLogger.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDAbstractDatabaseLogger.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDAssertMacros.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDAssertMacros.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDContextFilterLogFormatter.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/Extensions/DDContextFilterLogFormatter.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDDispatchQueueLogFormatter.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/Extensions/DDDispatchQueueLogFormatter.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDFileLogger.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDFileLogger.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDLog+LOGV.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDLog+LOGV.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDLog.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDLog.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDLogMacros.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDLogMacros.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDMultiFormatter.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/Extensions/DDMultiFormatter.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CocoaLumberjack/DDTTYLogger.h:
--------------------------------------------------------------------------------
1 | ../../../CocoaLumberjack/Classes/DDTTYLogger.h
--------------------------------------------------------------------------------
/Pods/Headers/Public/CrashlyticsFramework/Crashlytics.h:
--------------------------------------------------------------------------------
1 | ../../../CrashlyticsFramework/Crashlytics.framework/Versions/A/Headers/Crashlytics.h
--------------------------------------------------------------------------------
/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CocoaLumberjack (2.0.0-beta2):
3 | - CocoaLumberjack/CLI
4 | - CocoaLumberjack/Core
5 | - CocoaLumberjack/Extensions
6 | - CocoaLumberjack/CLI (2.0.0-beta2):
7 | - CocoaLumberjack/Core
8 | - CocoaLumberjack/Core (2.0.0-beta2)
9 | - CocoaLumberjack/Extensions (2.0.0-beta2):
10 | - CocoaLumberjack/Core
11 | - CrashlyticsFramework (2.2.5)
12 |
13 | DEPENDENCIES:
14 | - CocoaLumberjack
15 | - CrashlyticsFramework
16 |
17 | SPEC CHECKSUMS:
18 | CocoaLumberjack: 956d3fb98fed498a13d56499f262c975ef431c98
19 | CrashlyticsFramework: 82d124501d97d3b5d49bd6209dea21c6b7f0a33d
20 |
21 | COCOAPODS: 0.34.4
22 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CocoaLumberjack/Pods-CocoaLumberjack-Private.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods-CocoaLumberjack.xcconfig"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/CocoaLumberjack" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
4 | OTHER_LDFLAGS = -ObjC
5 | PODS_ROOT = ${SRCROOT}
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CocoaLumberjack/Pods-CocoaLumberjack-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_CocoaLumberjack : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_CocoaLumberjack
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CocoaLumberjack/Pods-CocoaLumberjack-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #endif
4 |
5 | #import "Pods-environment.h"
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CocoaLumberjack/Pods-CocoaLumberjack.xcconfig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cyupa/JenkinsCI-iOS/8e6856dcec7caa2450b09f4a6b6e64f34bf26568/Pods/Target Support Files/Pods-CocoaLumberjack/Pods-CocoaLumberjack.xcconfig
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CrashlyticsFramework/Pods-CrashlyticsFramework-Private.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods-CrashlyticsFramework.xcconfig"
2 | FRAMEWORK_SEARCH_PATHS = ${PODS_CRASHLYTICSFRAMEWORK_FRAMEWORK_SEARCH_PATHS}
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/CrashlyticsFramework" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
5 | OTHER_LDFLAGS = ${PODS_CRASHLYTICSFRAMEWORK_OTHER_LDFLAGS} -ObjC
6 | PODS_ROOT = ${SRCROOT}
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CrashlyticsFramework/Pods-CrashlyticsFramework-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_CrashlyticsFramework : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_CrashlyticsFramework
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CrashlyticsFramework/Pods-CrashlyticsFramework-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #endif
4 |
5 | #import "Pods-environment.h"
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods-CrashlyticsFramework/Pods-CrashlyticsFramework.xcconfig:
--------------------------------------------------------------------------------
1 | PODS_CRASHLYTICSFRAMEWORK_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PODS_ROOT)/CrashlyticsFramework"
2 | PODS_CRASHLYTICSFRAMEWORK_OTHER_LDFLAGS = -framework "Crashlytics"
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods/Pods-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods : NSObject
3 | @end
4 | @implementation PodsDummy_Pods
5 | @end
6 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods/Pods-environment.h:
--------------------------------------------------------------------------------
1 |
2 | // To check if a library is compiled with CocoaPods you
3 | // can use the `COCOAPODS` macro definition which is
4 | // defined in the xcconfigs so it is available in
5 | // headers also when they are imported in the client
6 | // project.
7 |
8 |
9 | // CocoaLumberjack
10 | #define COCOAPODS_POD_AVAILABLE_CocoaLumberjack
11 | #define COCOAPODS_VERSION_MAJOR_CocoaLumberjack 2
12 | #define COCOAPODS_VERSION_MINOR_CocoaLumberjack 0
13 | #define COCOAPODS_VERSION_PATCH_CocoaLumberjack 0
14 |
15 | // CocoaLumberjack/CLI
16 | #define COCOAPODS_POD_AVAILABLE_CocoaLumberjack_CLI
17 | #define COCOAPODS_VERSION_MAJOR_CocoaLumberjack_CLI 2
18 | #define COCOAPODS_VERSION_MINOR_CocoaLumberjack_CLI 0
19 | #define COCOAPODS_VERSION_PATCH_CocoaLumberjack_CLI 0
20 |
21 | // CocoaLumberjack/Core
22 | #define COCOAPODS_POD_AVAILABLE_CocoaLumberjack_Core
23 | #define COCOAPODS_VERSION_MAJOR_CocoaLumberjack_Core 2
24 | #define COCOAPODS_VERSION_MINOR_CocoaLumberjack_Core 0
25 | #define COCOAPODS_VERSION_PATCH_CocoaLumberjack_Core 0
26 |
27 | // CocoaLumberjack/Extensions
28 | #define COCOAPODS_POD_AVAILABLE_CocoaLumberjack_Extensions
29 | #define COCOAPODS_VERSION_MAJOR_CocoaLumberjack_Extensions 2
30 | #define COCOAPODS_VERSION_MINOR_CocoaLumberjack_Extensions 0
31 | #define COCOAPODS_VERSION_PATCH_CocoaLumberjack_Extensions 0
32 |
33 | // CrashlyticsFramework
34 | #define COCOAPODS_POD_AVAILABLE_CrashlyticsFramework
35 | #define COCOAPODS_VERSION_MAJOR_CrashlyticsFramework 2
36 | #define COCOAPODS_VERSION_MINOR_CrashlyticsFramework 2
37 | #define COCOAPODS_VERSION_PATCH_CrashlyticsFramework 5
38 |
39 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods/Pods-resources.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
5 |
6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
7 | > "$RESOURCES_TO_COPY"
8 |
9 | install_resource()
10 | {
11 | case $1 in
12 | *.storyboard)
13 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
14 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
15 | ;;
16 | *.xib)
17 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
18 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
19 | ;;
20 | *.framework)
21 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
22 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
23 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
24 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
25 | ;;
26 | *.xcdatamodel)
27 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
28 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
29 | ;;
30 | *.xcdatamodeld)
31 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
32 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
33 | ;;
34 | *.xcassets)
35 | ;;
36 | /*)
37 | echo "$1"
38 | echo "$1" >> "$RESOURCES_TO_COPY"
39 | ;;
40 | *)
41 | echo "${PODS_ROOT}/$1"
42 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
43 | ;;
44 | esac
45 | }
46 |
47 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
48 | if [[ "${ACTION}" == "install" ]]; then
49 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
50 | fi
51 | rm -f "$RESOURCES_TO_COPY"
52 |
53 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ]
54 | then
55 | case "${TARGETED_DEVICE_FAMILY}" in
56 | 1,2)
57 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
58 | ;;
59 | 1)
60 | TARGET_DEVICE_ARGS="--target-device iphone"
61 | ;;
62 | 2)
63 | TARGET_DEVICE_ARGS="--target-device ipad"
64 | ;;
65 | *)
66 | TARGET_DEVICE_ARGS="--target-device mac"
67 | ;;
68 | esac
69 | find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
70 | fi
71 |
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods/Pods.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PODS_ROOT)/CrashlyticsFramework"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/CocoaLumberjack" -isystem "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
5 | OTHER_LDFLAGS = -ObjC -l"Pods-CocoaLumberjack" -l"Pods-CrashlyticsFramework" -framework "Crashlytics"
6 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
7 | PODS_ROOT = ${SRCROOT}/Pods
--------------------------------------------------------------------------------
/Pods/Target Support Files/Pods/Pods.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PODS_ROOT)/CrashlyticsFramework"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/CocoaLumberjack" -isystem "${PODS_ROOT}/Headers/Public/CrashlyticsFramework"
5 | OTHER_LDFLAGS = -ObjC -l"Pods-CocoaLumberjack" -l"Pods-CrashlyticsFramework" -framework "Crashlytics"
6 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS)
7 | PODS_ROOT = ${SRCROOT}/Pods
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JenkinsCI-iOS
2 | =============
3 |
4 | A Jenkins job setup for your Xcode project.
5 |
6 | ## Contents:
7 | [Installing Jenkins](#installing-jenkins)
8 | [Xcode project setup](#xcode-project-setup)
9 | [Jenkins plugins](#jenkins-plugins)
10 | [Installing code metrics tools](#installing-code-metrics-tools)
11 | [Setting up the job](#setting-up-the-job)
12 | [Troubleshooting](#troubleshooting)
13 |
14 | ## Installing Jenkins
15 |
16 | Download Jenkins from here: https://www.jenkins.io/download/weekly/macos/
17 | I would recommend that the install should be made under the administrator user and not let the Jenkins installer create it's own user. That will generate issues when trying to access the keychain.
18 |
19 | To run Jenkins go to `/Applications/Jenkins` and run the `jenkins.war` file. Make sure you have the latest Java JDK installed.
20 |
21 | After that, you can access the Jenkins Dashboard using the following URL: [http://localhost:8080](http://localhost:8080)
22 |
23 | ## Xcode project setup
24 |
25 | First, go to your project target from the left top corner of Xcode, click on the target and select "Manage Schemes".
26 | There you should check the "Shared" option for your Xcode project (do not check shared for the Pods project).
27 | Target - > Manage schemes - > Check “Shared”
28 |
29 | Then, in the project's Build Settings turn on Generate Test Coverage Files and Instrument Program Flow for the Debug configuration on your main target and for both Debug an Release for your test target.
30 |
31 | To take advantage of the generated files you need to set the Build Products and Intermediates to be saved in a folder relative to the Workspace. You can do this by accessing Xcode Preferences -> Locations -> Custom -> Relative to Workspace.
32 |
33 |
34 | To check if everything it's OK you can build the project and check the following folders for .gcno and .gcda files
35 | `Build/Intermediates/YOUR-TEST-TARGET-NAME.build/Objects-normal/i386'`
36 | and
37 | `Build/Intermediates/YOUR-MAIN-TARGET-NAME.build/Objects-normal/i386'`
38 | You can find these based on the setting you have in Xcode for Locations.
39 |
40 | ## Jenkins plugins
41 | To setup you job, you will need the following plugins:
42 |
43 | Xcode plugin
44 | Git plugin
45 | Keychains and Provisioning Profiles Plugin
46 | Duplicate Code Scanner Plug-in
47 | Cobertura plugin
48 | SLOCCount Plugin
49 | EnvInject Plugin
50 |
51 | To add Jenkins plugins you must go to Jenkins -> Manage Jenkins -> Manage plugins.
52 |
53 | ## Installing code metrics tools
54 | ##### Install Homebrew
55 | To install Homebrew, simply copy-paste this code into your Terminal and press enter:
56 |
57 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
58 |
59 | ##### Installing sloccount: `brew install sloccount`
60 |
61 | ##### Installing xctool: `brew install xctool`
62 |
63 | ##### Installing pmd:
64 | You can download 4.3 from [here](http://sourceforge.net/projects/pmd/files/pmd/4.3/pmd-bin-4.3.zip/download). The latest versions have suffered major changes that aren't supported by the ObjectiveC language definition yet.
65 | To be able to make use of PMD you will also need to dowload the PMD Objective-C language definition from [here](https://github.com/jkennedy1980/Objective-C-CPD-Language/blob/master/releases/ObjCLanguage-0.0.7-SNAPSHOT.jar) - courtesy of Josh Kennedy.
66 |
67 |
68 | ##### Installing gcovr:
69 | ```
70 | cd ~
71 | git clone https://github.com/gcovr/gcovr.git
72 | sudo cp ./gcovr/scripts/gcovr /usr/local/bin
73 | sudo chown root:wheel /usr/local/bin/gcovr
74 | sudo chmod 755 /usr/local/bin/gcovr
75 | cd ~
76 | rm -rf ./gcovr/
77 | ```
78 |
79 |
80 | ## Setting up the job
81 |
82 | Here comes the fun part: setting up the Jenkins job.
83 | The first step is creating the job: New item -> Freestyle project. This will let you do all the configuration of a job.
84 |
85 | #### Source Code Management
86 | Our project is usually stored in a Git or SVN repository. The Jenkins job begins with this step: cloning the latest version of your branch.
87 | You can setup this by adding your repository info & credentials in the Source Code Management section. For our job, we have a GitHub repostiory: https://github.com/cyupa/JenkinsCI-iOS.git and your GitHub credentials. Then you can specify the branch you want to clone and build, in this case: `*/master`.
88 |
89 | #### Build Environment
90 | A Jenkins job does not have access to environment variables such as PATH, that allows us the invoke different scripts and tools without specifing the full path to that script. This scripts are stored at different locations and this variable knows about those locations.
91 |
92 | You can check the PATH variableby opening a Terminal window and type `echo $PATH`.
93 | In my case: `/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin:/usr/local/Cellar/`
94 |
95 | Next, in the Build Environment section, we will add the line `PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin:/usr/local/Cellar/` in the Properties Content field.
96 |
97 | #### Running tests
98 |
99 | Before we go on, we should run our unit tests on our project, to make sure everything is OK.
100 | Add a new Execute Shell build step with the following code:
101 | ```
102 | xctool -workspace ${WORKSPACE}/JenkinsCI.xcworkspace \
103 | -scheme JenkinsCI \
104 | -reporter plain \
105 | -sdk iphonesimulator \
106 | -reporter junit:test-reports/ios-report.xml \
107 | test \
108 | -resetSimulator \
109 | -freshInstall
110 | ```
111 | After this, add a Publish JUnit test results post build action to view the results of your test in your Dashboard.
112 |
113 | At this point you can take a step back and try to build the project to check if everything is ok.
114 |
115 | #### Compute code coverage
116 |
117 | Obtaining code coverage can be tricky. First, you must check that your Intermediates/{PROJECT NAME}.build/Debug-iphonesimulator/{PROJECT NAME}.build/Objects-normal/i386 contains .gcno and .gcda files. After that, running the following command via an Execute shell build step will generate the code coverage.
118 |
119 | ```
120 | gcovr -r . --object-directory ${WORKSPACE}/Build/Intermediates/JenkinsCI.build/Debug-iphonesimulator/JenkinsCI.build/Objects-normal/i386 --exclude '.*Tests.*' --xml > ${WORKSPACE}/test-reports/ios-cobertura-coverage.xml
121 | ```
122 |
123 | The results can be published by adding a "Publish Cobertura coverage report" as a post build step.
124 |
125 | #### Lines of code metric
126 |
127 | This one is quite simple: it runs a script to see the total lines of code in your project, modules and in each file. To take advantage of SLOCCount you must add a build step with an Execute shell script:
128 | ```
129 | sloccount --duplicates --wide --details ${WORKSPACE}/JenkinsCI/Classes > ${WORKSPACE}/test-reports/ios-sloccount.sc
130 | ```
131 | Then you can publish the results just by adding a Post build step: Publish SLOCCount analisys results and use the `test-reports/ios-sloccount.sc` output as a source.
132 |
133 | #### Duplicate code metric
134 |
135 | Now comes the tricky part: setting up the duplicate code metric.
136 | We'll be using PMD 4.2.6 because the ObjectiveC Language dictionary isn't up to date with the latest PMD versions. After you downloaded both (links posted up in the Read me file), you must use the full path to the files you compose your shell script.
137 | In my case I have dowloaded the files in `/usr/local/Cellar/pmd/`. In this case, the script will look something like this:
138 |
139 | ```
140 | java -Xmx512m -classpath /usr/local/Cellar/pmd/4.3/lib/pmd-4.3.jar:/usr/local/Cellar/pmd/ObjCLanguage-0.0.7-SNAPSHOT.jar net.sourceforge.pmd.cpd.CPD \
141 | --minimum-tokens 100 \
142 | --files ${WORKSPACE}/JenkinsCI/Classes \
143 | --language ObjectiveC \
144 | --encoding UTF-8 \
145 | --format net.sourceforge.pmd.cpd.XMLRenderer > ${WORKSPACE}/test-reports/ios-cpd-output.xml
146 | ```
147 |
148 | If the `test-reports/ios-cpd-output.xml` is generated you can publish the results by adding a Publish duplicate code analisys results in the Post build section.
149 |
150 | #### Xcode build
151 |
152 | If everything is fine until this point, you can move on to the buil & distribute part of the job.
153 | Go on and add an Xcode build step. This plugin will invoke the xcodebuild command line tool and you can add all the build parameters here. Keep in mind that I'm using CocoaPods.
154 |
155 | In this case:
156 | * Target: JenkinsCI
157 | * Clean before build? YES
158 | * Generate Archive? YES
159 | * Pack application and build .ipa? YES
160 | * .ipa filename pattern: ${VERSION}
161 | * Output directory: ${workspace}/Builds/${BUILD_NUMBER}/${BUILD_ID}
162 | * Unlock Keychain? YES
163 | * Keychain path: ${HOME}/Library/Keychains/login.keychain
164 | * Keychain password: your administrator user password
165 | * Xcode Schema File: JenkinsCI
166 | * Xcode Workspace File: ${WORKSPACE}/JenkinsCI
167 | * Xcode Project Directory: ${WORKSPACE}
168 | * Xcode Project File: ${WORKSPACE}/JenkinsCI
169 | * Build output directory: ${WORKSPACE}/Build
170 | * Provide version number and run avgtool? YES
171 | * Technical version: ${BUILD_ID}
172 |
173 |
174 | After you configured this to your needs you should check if the job finishes successfully before moving on to the next step.
175 |
176 | #### Upload to Crashlytics
177 |
178 | The Crashlytics frameworks comes with a really nice tool to distribute your build to the testers, client and your team. To simply upload and notify your user groups about a new build you can add another Execute shell build step with the following command:
179 | ```
180 | ${WORKSPACE}/Pods/CrashlyticsFramework/Crashlytics.framework/submit \
181 | \
182 | \
183 | -ipaPath ${WORKSPACE}/builds/${BUILD_NUMBER}/${BUILD_ID}/${BUILD_ID}.ipa \
184 | -groupAliases clients,developers,testers \
185 | ```
186 |
187 |
188 | If you would like to add some notes to your upload you could add a "Release notes extractios" step. You can do this by adding an Execute shell build step:
189 | ```
190 | curl -s "http://localhost:8080/job/JenkinsCI/$BUILD_NUMBER/api/xml?wrapper=changes&xpath=//changeSet//comment" | sed -e "s/<\/comment>//g; s///g; s/<\/*changes\/*>//g" | sed '/^$/d;G' > ${WORKSPACE}/changelog.txt
191 | ```
192 | This will extract the comments from your commits since the last build and put them into the changelog.txt file. Once you've done this, add the following option in your Crashlytics submission script: `-notesPath ${WORKSPACE}/changelog.txt \`.
193 |
194 | ## Troubleshooting
195 |
196 | ###### Homebrew dependencies
197 | If you encounter issues when running 'brew install sloccount' such as:
198 | `looking for OpenSSL headers 'openssl/md5.h'... Cannot find it.
199 | Please run this script as such: SSLINCPATH= ./configure`
200 |
201 | Install OpenSSL via Homebrew ('brew install openssl') and retry.
202 | If that doesn't work, go to /Library/Caches/Homebrew/, unpack the md5sha1sum archive, open it, and run the following command in the Terminal: SSLINCPATH=/usr/local/Cellar/openssl/1.0.1i/include ./configure.
203 |
204 | ###### Linker errors while building with Xcode 6
205 | If your build fails with a linker error in the Build step while trying to build and archive (for some reason xcodebuild tries to build the test scheme in the Archive configuration) for some class included in your test case, go to Build Settings and turn Symbols Hidden by Default to NO on your main target.
206 |
--------------------------------------------------------------------------------