Skip to content

Commit

Permalink
Merge pull request #131 from EddyLB/master
Browse files Browse the repository at this point in the history
Improved connection management
  • Loading branch information
EddyLB committed May 29, 2017
2 parents f4f9991 + 9850511 commit 851b115
Show file tree
Hide file tree
Showing 12 changed files with 434 additions and 39 deletions.
6 changes: 6 additions & 0 deletions piwigo.xcodeproj/project.pbxproj
Expand Up @@ -12,6 +12,7 @@
AD0134641EBE310000F11C3F /* TabBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AD0134631EBE310000F11C3F /* TabBarViewController.m */; };
AD35CA381E9BF8A600E3B897 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AD35CA361E9BF8A600E3B897 /* Launch Screen.storyboard */; };
AD35CA3A1E9C1EBC00E3B897 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AD35CA391E9C1EBC00E3B897 /* Images.xcassets */; };
AD6D203C1EDC45C4003B60E8 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = AD6D203B1EDC45C4003B60E8 /* Reachability.m */; };
D8083A4F1A7CB65400A95605 /* UIActionSheet+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = D8083A4E1A7CB65400A95605 /* UIActionSheet+Blocks.m */; };
D8083A521A7CB78900A95605 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = D8083A511A7CB78900A95605 /* UIAlertView+Blocks.m */; };
D8083A551A7D66CD00A95605 /* ImageService.m in Sources */ = {isa = PBXBuildFile; fileRef = D8083A541A7D66CD00A95605 /* ImageService.m */; };
Expand Down Expand Up @@ -123,6 +124,8 @@
AD0134631EBE310000F11C3F /* TabBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabBarViewController.m; sourceTree = "<group>"; };
AD35CA371E9BF8A600E3B897 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = "piwigo/Base.lproj/Launch Screen.storyboard"; sourceTree = "<group>"; };
AD35CA391E9C1EBC00E3B897 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
AD6D203A1EDC45C4003B60E8 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = "<group>"; };
AD6D203B1EDC45C4003B60E8 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = "<group>"; };
B37F5B7464A6A11CDDABA253 /* libPods-piwigoTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-piwigoTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
D8083A4D1A7CB65400A95605 /* UIActionSheet+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+Blocks.h"; sourceTree = "<group>"; };
D8083A4E1A7CB65400A95605 /* UIActionSheet+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+Blocks.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -653,6 +656,8 @@
children = (
D82B8CE41A678ED2000E47CA /* NetworkHandler.h */,
D82B8CE51A678ED2000E47CA /* NetworkHandler.m */,
AD6D203A1EDC45C4003B60E8 /* Reachability.h */,
AD6D203B1EDC45C4003B60E8 /* Reachability.m */,
);
name = Network;
sourceTree = "<group>";
Expand Down Expand Up @@ -1111,6 +1116,7 @@
D89045B91A946A5B00A306FE /* TagsService.m in Sources */,
D8C71A471A8489CF0048BA33 /* ImageUploadViewController.m in Sources */,
D82B8CE61A678ED2000E47CA /* NetworkHandler.m in Sources */,
AD6D203C1EDC45C4003B60E8 /* Reachability.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
35 changes: 18 additions & 17 deletions piwigo/AlbumImagesViewController.m
Expand Up @@ -135,7 +135,7 @@ -(void)viewDidAppear:(BOOL)animated

-(void)refresh:(UIRefreshControl*)refreshControl
{
[self.albumData reloadAlbumOnCompletion:^{
[self.albumData loadAllImagesOnCompletion:^{
[refreshControl endRefreshing];
[self.imagesCollection reloadData];
}];
Expand Down Expand Up @@ -426,27 +426,28 @@ -(UICollectionReusableView*)collectionView:(UICollectionView *)collectionView vi
{
if(indexPath.section == 1)
{
SortHeaderCollectionReusableView *header = nil;

if(kind == UICollectionElementKindSectionHeader)
self.noImagesLabel = [UILabel new];
self.noImagesLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.noImagesLabel.font = [UIFont piwigoFontNormal];
self.noImagesLabel.font = [self.noImagesLabel.font fontWithSize:20];
self.noImagesLabel.textColor = [UIColor piwigoWhiteCream];
self.noImagesLabel.text = NSLocalizedString(@"noImages", @"No Images");
self.noImagesLabel.hidden = self.albumData.images.count != 0;

SortHeaderCollectionReusableView *header = nil;

if(kind == UICollectionElementKindSectionHeader)
{
header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
header.currentSortLabel.text = [CategorySortViewController getNameForCategorySortType:self.currentSortCategory];
[header addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didSelectCollectionViewHeader)]];

[header addSubview:self.noImagesLabel];
[header addConstraint:[NSLayoutConstraint constraintViewFromBottom:self.noImagesLabel amount:-40]];
[header addConstraint:[NSLayoutConstraint constraintCenterVerticalView:self.noImagesLabel]];

return header;
}

self.noImagesLabel = [UILabel new];
self.noImagesLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.noImagesLabel.font = [UIFont piwigoFontNormal];
self.noImagesLabel.font = [self.noImagesLabel.font fontWithSize:20];
self.noImagesLabel.textColor = [UIColor piwigoWhiteCream];
self.noImagesLabel.text = NSLocalizedString(@"noImages", @"No Images");
self.noImagesLabel.hidden = self.albumData.images.count != 0;
[header addSubview:self.noImagesLabel];
[header addConstraint:[NSLayoutConstraint constraintViewFromBottom:self.noImagesLabel amount:-40]];
[header addConstraint:[NSLayoutConstraint constraintCenterVerticalView:self.noImagesLabel]];

return header;
}

UICollectionReusableView *view = [[UICollectionReusableView alloc] initWithFrame:CGRectZero];
Expand Down
83 changes: 82 additions & 1 deletion piwigo/AppDelegate.m
Expand Up @@ -15,13 +15,15 @@
#import "Model.h"
#import "KeychainAccess.h"
#import "AFNetworkActivityIndicatorManager.h"
#import "Reachability.h"

#import "PhotosFetch.h"
#import "iRate.h"

@interface AppDelegate ()

@property (nonatomic, strong) LoginViewController *loginVC;
@property (nonatomic, strong) Reachability *internetReachability;

@end

Expand All @@ -40,7 +42,8 @@ + (void)initialize {


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

// Override point for customization after application launch.

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:[Model sharedInstance].memoryCache * 1024*1024
diskCapacity:[Model sharedInstance].diskCache * 1024*1024
Expand Down Expand Up @@ -70,6 +73,84 @@ -(void)loadNavigation
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:navigation];
[self.loginVC removeFromParentViewController];
self.loginVC = nil;

// Observe the kNetworkReachabilityChangedNotification.
// When that notification is posted, the method reachabilityChanged will be called.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];

// Monitor Internet connection reachability
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
}

// Called by Reachability whenever Internet connection changes.
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability* curReach = [note object];
NetworkStatus netStatus = [curReach currentReachabilityStatus];

switch (netStatus)
{
case NotReachable:
{
// NSLog(@"Access Not Available");
break;
}
case ReachableViaWWAN:
{
// Connection changed but now reachable WWAN — Login again?
BOOL hadOpenedSession = [Model sharedInstance].hadOpenedSession;
NSString *server = [Model sharedInstance].serverName;
NSString *user = [KeychainAccess getLoginUser];
NSString *password = [KeychainAccess getLoginPassword];

if(hadOpenedSession && (server.length > 0) && (user.length > 0))
{
[SessionService performLoginWithUser:user
andPassword:password
onCompletion:^(BOOL result, id response) {
[Model sharedInstance].hadOpenedSession = YES;
}
onFailure:^(NSURLSessionTask *task, NSError *error) {
[Model sharedInstance].hadOpenedSession = NO;
NSLog(@"Error %ld: %@", (long)error.code, error.localizedDescription);
[UIAlertView showWithTitle:NSLocalizedString(@"internetErrorGeneral_title", @"Connection Error")
message:[error localizedDescription]
cancelButtonTitle:NSLocalizedString(@"alertOkButton", @"OK")
otherButtonTitles:nil
tapBlock:nil];
}];
}
break;
}
case ReachableViaWiFi:
{
// Connection changed but now reachable WiFi — Login again?
BOOL hadOpenedSession = [Model sharedInstance].hadOpenedSession;
NSString *server = [Model sharedInstance].serverName;
NSString *user = [KeychainAccess getLoginUser];
NSString *password = [KeychainAccess getLoginPassword];

if(hadOpenedSession && (server.length > 0) && (user.length > 0))
{
[SessionService performLoginWithUser:user
andPassword:password
onCompletion:^(BOOL result, id response) {
[Model sharedInstance].hadOpenedSession = YES;
}
onFailure:^(NSURLSessionTask *task, NSError *error) {
[Model sharedInstance].hadOpenedSession = NO;
NSLog(@"Error %ld: %@", (long)error.code, error.localizedDescription);
[UIAlertView showWithTitle:NSLocalizedString(@"internetErrorGeneral_title", @"Connection Error")
message:[error localizedDescription]
cancelButtonTitle:NSLocalizedString(@"alertOkButton", @"OK")
otherButtonTitles:nil
tapBlock:nil];
}];
}
break;
}
}
}

-(void)loadLoginView
Expand Down
17 changes: 11 additions & 6 deletions piwigo/LoginViewController.m
Expand Up @@ -131,19 +131,23 @@ -(void)performLogin
[Model sharedInstance].serverProtocol = [self.serverTextField getProtocolString];
[[Model sharedInstance] saveToDisk];

if(self.userTextField.text.length > 0)
if(self.userTextField.text.length > 0) // Perform Login if username exists
{
[SessionService performLoginWithUser:self.userTextField.text
andPassword:self.passwordTextField.text
onCompletion:^(BOOL result, id response) {
if(result)
{
[self getSessionStatus];
[self getSessionPluginsList];
[Model sharedInstance].hadOpenedSession = YES;
[self getSessionStatus];
if([Model sharedInstance].hasAdminRights) {
[self getSessionPluginsList]; // To determine if VideoJS is active
}
}
else
{
[self hideLoading];
[Model sharedInstance].hadOpenedSession = NO;
[self hideLoading];
[self showLoginFail];
}
} onFailure:^(NSURLSessionTask *task, NSError *error) {
Expand All @@ -157,9 +161,10 @@ -(void)performLogin
tapBlock:nil];
}];
}
else
else // No username, get only session status
{
[self getSessionStatus];
[Model sharedInstance].hadOpenedSession = NO;
[self getSessionStatus];
[KeychainAccess resetKeychain];
}
}
Expand Down
1 change: 1 addition & 0 deletions piwigo/Model.h
Expand Up @@ -38,6 +38,7 @@ typedef enum {
@property (nonatomic, assign) BOOL hasAdminRights;
@property (nonatomic, assign) BOOL hasInstalledVideoJS;
@property (nonatomic, assign) BOOL hasUploadedImages;
@property (nonatomic, assign) BOOL hadOpenedSession;

@property (nonatomic, assign) kPiwigoPrivacy defaultPrivacyLevel;
@property (nonatomic, strong) NSString *defaultAuthor;
Expand Down
10 changes: 2 additions & 8 deletions piwigo/Model.m
Expand Up @@ -28,8 +28,9 @@ + (Model*)sharedInstance
instance.defaultPrivacyLevel = kPiwigoPrivacyEverybody;
instance.defaultAuthor = @"";
instance.hasAdminRights = NO;
instance.hadOpenedSession = NO;
instance.hasUploadedImages = NO;
instance.hasInstalledVideoJS = NO;
instance.hasInstalledVideoJS = YES; // Will be checked if the user has admin rights
instance.stripGPSdataOnUpload = NO;
instance.photoQuality = 95;
instance.photoResize = 100;
Expand Down Expand Up @@ -125,7 +126,6 @@ - (void)readFromDisk
self.resizeImageOnUpload = modelData.resizeImageOnUpload;
self.defaultImagePreviewSize = modelData.defaultImagePreviewSize;
self.stripGPSdataOnUpload = modelData.stripGPSdataOnUpload;
self.hasInstalledVideoJS = modelData.hasInstalledVideoJS;
}
}

Expand Down Expand Up @@ -154,7 +154,6 @@ - (void) encodeWithCoder:(NSCoder *)encoder {
[saveObject addObject:[ NSNumber numberWithBool:self.resizeImageOnUpload]];
[saveObject addObject:@(self.defaultImagePreviewSize)];
[saveObject addObject:[NSNumber numberWithBool:self.stripGPSdataOnUpload]];
[saveObject addObject:[NSNumber numberWithBool:self.hasInstalledVideoJS]];

[encoder encodeObject:saveObject forKey:@"Model"];
}
Expand Down Expand Up @@ -203,11 +202,6 @@ - (id)initWithCoder:(NSCoder *)decoder {
} else {
self.stripGPSdataOnUpload = NO;
}
if(savedData.count > 13) {
self.hasInstalledVideoJS = [[savedData objectAtIndex:13] boolValue];
} else {
self.hasInstalledVideoJS = NO;
}

return self;
}
Expand Down
2 changes: 1 addition & 1 deletion piwigo/PiwigoAlbumData.m
Expand Up @@ -110,7 +110,7 @@ -(void)loadCategoryImageDataChunkWithSort:(NSString*)sort
if(error)
{
[UIAlertView showWithTitle:NSLocalizedString(@"albumPhotoError_title", @"Get Album Photos Error")
message:[NSString stringWithFormat:@"%@\n%@", NSLocalizedString(@"albumPhotoError_message", @"Failed to get album photos (You probably have a corrupt image in your album) Error:"), [error localizedDescription]]
message:[NSString stringWithFormat:@"%@\n%@", NSLocalizedString(@"albumPhotoError_message", @"Failed to get album photos (corrupt image in your album?)"), [error localizedDescription]]
cancelButtonTitle:NSLocalizedString(@"alertOkButton", @"OK")
otherButtonTitles:nil
tapBlock:nil];
Expand Down
64 changes: 64 additions & 0 deletions piwigo/Reachability.h
@@ -0,0 +1,64 @@
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
Basic demonstration of how to use the SystemConfiguration Reachablity APIs.
*/

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>


typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;

#pragma mark IPv6 Support
//Reachability fully support IPv6. For full details, see ReadMe.md.


extern NSString *kReachabilityChangedNotification;


@interface Reachability : NSObject

/*!
* Use to check the reachability of a given host name.
*/
+ (instancetype)reachabilityWithHostName:(NSString *)hostName;

/*!
* Use to check the reachability of a given IP address.
*/
+ (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

/*!
* Checks whether the default route is available. Should be used by applications that do not connect to a particular host.
*/
+ (instancetype)reachabilityForInternetConnection;


#pragma mark reachabilityForLocalWiFi
//reachabilityForLocalWiFi has been removed from the sample. See ReadMe.md for more information.
//+ (instancetype)reachabilityForLocalWiFi;

/*!
* Start listening for reachability notifications on the current run loop.
*/
- (BOOL)startNotifier;
- (void)stopNotifier;

- (NetworkStatus)currentReachabilityStatus;

/*!
* WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.
*/
- (BOOL)connectionRequired;

@end


0 comments on commit 851b115

Please sign in to comment.