Firstly, thanks for sharing the frameworks - very powerful and flexible.
I have been working with them, and have some suggestions for improvements and bug fixes for the iOS frameworks:
--------------------------------
Description: The file item was not being passed to the delegate
File: OUIDocumentPickerViewController.m
Method: - (NSString *)printTitle
Change From: return [delegate documentPicker:_documentPicker printButtonTitleForFileItem:nil];
Change To: return [delegate documentPicker:_documentPicker printButtonTitleForFileItem:self.singleSelectedFil eItem];
---------------------------------
Description: When changing filters, the previously selected items are still selected even if they are no longer visible. This can lead to situations where the user has no idea how to just select a single file to work with it. This affects your apps.
File: OUIDocumentPickerViewController.m
Method: - (void)selectedFilterChanged
Add: [self clearSelection:NO]; before [self updateTitle];
-----------------------------------
Description: The export item in the toolbar is incorrectly enabled/disabled and ditto for the duplicate option. This affects your apps, and can lead to a crash.
File: OUIDocumentPickerViewController.m
Method: - (void)_updateToolbarItemsEnabledness
Revised code:
- (void)_updateToolbarItemsEnabledness;
{
if (self.isEditing) {
NSUInteger count = self.selectedItemCount;
if (count == 0) {
_exportBarButtonItem.enabled = NO;
_moveBarButtonItem.enabled = NO;
_duplicateDocumentBarButtonItem.enabled = NO;
_deleteBarButtonItem.enabled = NO;
} else {
// We can export files if we only have a single one selected and it's not a folder, and the selected file has at least one export type.
BOOL canExport = NO;
if (count == 1 && !self.hasSelectedFolder) {
canExport = ([[self availableExportTypesForFileItem:self.singleSelecte dFileItem serverAccount:nil exportOptionsType:OUIExportOptionsNone] count] > 0);
}
// We can duplicate single or multiple files so long as we are not in the trash and we don't have a folder selected
BOOL canDuplicate = NO;
if (!self.selectedScope.isTrash && !self.hasSelectedFolder) {
canDuplicate = YES;
}
_exportBarButtonItem.enabled = canExport;
// The Move option should also be available if someone has selected a file or folder, since we should be able to move it to a folder.
_moveBarButtonItem.enabled = YES;
_duplicateDocumentBarButtonItem.enabled = canDuplicate;
// If single or multiple items are selected, no matter what they are, we can delete them.
_deleteBarButtonItem.enabled = YES;
}
}
}
-----------------------------------------
Description: In our case, we wanted to put a title on the app menu, and had to edit the _showAppMenu: method of OUIAppController. Suggest this be set up so that it can be implemented in a subclass.
------------------------------------------
Description: The help web view was appearing with a dark title bar on iOS 7.
File: OUIAppController.m
Method: - (void)_showWebViewWithURL:(NSURL *)url title:(NSString *)title
Suggestion: either change the barStyle from UIBarStyleBlack to UIBarStyleDefault, or make it configurable.
-------------------------------------------
Description: The online store purchase options all appear in the main menu, which is not nice if there are a lot of purchase options.
File: OUIAppController.m
Suggestion: Make it so that you can either have the purchase options all in the main menu or add a submenu if required. This requires two changes:
Add the following method:
/*!
If we return a string from this (in a subclass), then the app store purchases will go in a submenu
with that title.
*/
- (NSString *)purchaseSubMenuTitle {
return nil;
}
and then update - (NSArray *)menuControllerOptions:(OUIMenuController *)menu as follows:
....
additionalOptions = [self additionalAppMenuOptionsAtPosition:OUIAppMenuOptio nPositionAfterReleaseNotes];
if (additionalOptions)
[options addObjectsFromArray:additionalOptions];
// Need this so we can add a submenu if required.
NSMutableArray *purchaseMenuOptions = [NSMutableArray new];
NSString *purchaseSubMenuTitle = [self purchaseSubMenuTitle];
for (NSString *inAppPurchaseIdentifier in [self inAppPurchaseIdentifiers]) {
NSString *inAppPurchaseTitle = [self purchaseMenuItemTitleForInAppStoreProductIdentifie r:inAppPurchaseIdentifier];
if (!inAppPurchaseIdentifier)
continue;
option = [[OUIMenuOption alloc] initWithTitle:inAppPurchaseTitle image:menuImage(@"OUIMenuItemPurchases.png") action:^{
[[OUIAppController controller] showInAppPurchases:inAppPurchaseIdentifier navigationController:nil];
}];
[purchaseMenuOptions addObject:option];
}
if (purchaseSubMenuTitle) {
// We need to add a submenu for the purchases.
OUIMenuOption *purchaseOption = [[OUIMenuOption alloc] initWithTitle:@"Buy Extensions" image:[UIImage imageNamed:@"OUIMenuItemPurchases"]
options:purchaseMenuOptions destructive:NO action:nil];
[options addObject:purchaseOption];
} else {
[options addObjectsFromArray:purchaseMenuOptions];
}
additionalOptions = [self additionalAppMenuOptionsAtPosition:OUIAppMenuOptio nPositionAtEnd];
if (additionalOptions)
[options addObjectsFromArray:additionalOptions];
...
------------------------------------------
Additional notes: I wanted to make it possible to have specific account types where we didn't allow for import and export of files, since the actual file structure of the account would be hidden from the users. We therefore added an allowsExport property to the OFXServerAccountType and made the related other changes - not sure if this is a generally useful thing, but if you want, I can share the details of this update.
In OUIAppController (InAppStore) it would be nice if kKeychainIdentifier was not defined as a const, or at least had the ability to be overridden rather than me having to edit the file to change to my own identifier. E.g. by having a class method that returns the const, and update the other methods to call the class method instead of using the variable directly - then I could override that class method in my subclass to return my identifier.
I hope this is useful in improving the frameworks for everyone.
I have been working with them, and have some suggestions for improvements and bug fixes for the iOS frameworks:
--------------------------------
Description: The file item was not being passed to the delegate
File: OUIDocumentPickerViewController.m
Method: - (NSString *)printTitle
Change From: return [delegate documentPicker:_documentPicker printButtonTitleForFileItem:nil];
Change To: return [delegate documentPicker:_documentPicker printButtonTitleForFileItem:self.singleSelectedFil eItem];
---------------------------------
Description: When changing filters, the previously selected items are still selected even if they are no longer visible. This can lead to situations where the user has no idea how to just select a single file to work with it. This affects your apps.
File: OUIDocumentPickerViewController.m
Method: - (void)selectedFilterChanged
Add: [self clearSelection:NO]; before [self updateTitle];
-----------------------------------
Description: The export item in the toolbar is incorrectly enabled/disabled and ditto for the duplicate option. This affects your apps, and can lead to a crash.
File: OUIDocumentPickerViewController.m
Method: - (void)_updateToolbarItemsEnabledness
Revised code:
- (void)_updateToolbarItemsEnabledness;
{
if (self.isEditing) {
NSUInteger count = self.selectedItemCount;
if (count == 0) {
_exportBarButtonItem.enabled = NO;
_moveBarButtonItem.enabled = NO;
_duplicateDocumentBarButtonItem.enabled = NO;
_deleteBarButtonItem.enabled = NO;
} else {
// We can export files if we only have a single one selected and it's not a folder, and the selected file has at least one export type.
BOOL canExport = NO;
if (count == 1 && !self.hasSelectedFolder) {
canExport = ([[self availableExportTypesForFileItem:self.singleSelecte dFileItem serverAccount:nil exportOptionsType:OUIExportOptionsNone] count] > 0);
}
// We can duplicate single or multiple files so long as we are not in the trash and we don't have a folder selected
BOOL canDuplicate = NO;
if (!self.selectedScope.isTrash && !self.hasSelectedFolder) {
canDuplicate = YES;
}
_exportBarButtonItem.enabled = canExport;
// The Move option should also be available if someone has selected a file or folder, since we should be able to move it to a folder.
_moveBarButtonItem.enabled = YES;
_duplicateDocumentBarButtonItem.enabled = canDuplicate;
// If single or multiple items are selected, no matter what they are, we can delete them.
_deleteBarButtonItem.enabled = YES;
}
}
}
-----------------------------------------
Description: In our case, we wanted to put a title on the app menu, and had to edit the _showAppMenu: method of OUIAppController. Suggest this be set up so that it can be implemented in a subclass.
------------------------------------------
Description: The help web view was appearing with a dark title bar on iOS 7.
File: OUIAppController.m
Method: - (void)_showWebViewWithURL:(NSURL *)url title:(NSString *)title
Suggestion: either change the barStyle from UIBarStyleBlack to UIBarStyleDefault, or make it configurable.
-------------------------------------------
Description: The online store purchase options all appear in the main menu, which is not nice if there are a lot of purchase options.
File: OUIAppController.m
Suggestion: Make it so that you can either have the purchase options all in the main menu or add a submenu if required. This requires two changes:
Add the following method:
/*!
If we return a string from this (in a subclass), then the app store purchases will go in a submenu
with that title.
*/
- (NSString *)purchaseSubMenuTitle {
return nil;
}
and then update - (NSArray *)menuControllerOptions:(OUIMenuController *)menu as follows:
....
additionalOptions = [self additionalAppMenuOptionsAtPosition:OUIAppMenuOptio nPositionAfterReleaseNotes];
if (additionalOptions)
[options addObjectsFromArray:additionalOptions];
// Need this so we can add a submenu if required.
NSMutableArray *purchaseMenuOptions = [NSMutableArray new];
NSString *purchaseSubMenuTitle = [self purchaseSubMenuTitle];
for (NSString *inAppPurchaseIdentifier in [self inAppPurchaseIdentifiers]) {
NSString *inAppPurchaseTitle = [self purchaseMenuItemTitleForInAppStoreProductIdentifie r:inAppPurchaseIdentifier];
if (!inAppPurchaseIdentifier)
continue;
option = [[OUIMenuOption alloc] initWithTitle:inAppPurchaseTitle image:menuImage(@"OUIMenuItemPurchases.png") action:^{
[[OUIAppController controller] showInAppPurchases:inAppPurchaseIdentifier navigationController:nil];
}];
[purchaseMenuOptions addObject:option];
}
if (purchaseSubMenuTitle) {
// We need to add a submenu for the purchases.
OUIMenuOption *purchaseOption = [[OUIMenuOption alloc] initWithTitle:@"Buy Extensions" image:[UIImage imageNamed:@"OUIMenuItemPurchases"]
options:purchaseMenuOptions destructive:NO action:nil];
[options addObject:purchaseOption];
} else {
[options addObjectsFromArray:purchaseMenuOptions];
}
additionalOptions = [self additionalAppMenuOptionsAtPosition:OUIAppMenuOptio nPositionAtEnd];
if (additionalOptions)
[options addObjectsFromArray:additionalOptions];
...
------------------------------------------
Additional notes: I wanted to make it possible to have specific account types where we didn't allow for import and export of files, since the actual file structure of the account would be hidden from the users. We therefore added an allowsExport property to the OFXServerAccountType and made the related other changes - not sure if this is a generally useful thing, but if you want, I can share the details of this update.
In OUIAppController (InAppStore) it would be nice if kKeychainIdentifier was not defined as a const, or at least had the ability to be overridden rather than me having to edit the file to change to my own identifier. E.g. by having a class method that returns the const, and update the other methods to call the class method instead of using the variable directly - then I could override that class method in my subclass to return my identifier.
I hope this is useful in improving the frameworks for everyone.