Authored by Thomas Rasch

o use NSURLConnection for network tile fetches

o retryCount and waitSeconds as properties
(Closes #23 and #24)
@@ -28,11 +28,14 @@ @@ -28,11 +28,14 @@
28 #import "RMAbstractMercatorTileSource.h" 28 #import "RMAbstractMercatorTileSource.h"
29 #import "RMProjection.h" 29 #import "RMProjection.h"
30 30
31 -#define RMAbstractWebMapSourceRetryCount 3  
32 -#define RMAbstractWebMapSourceWaitSeconds 2 31 +#define RMAbstractWebMapSourceDefaultRetryCount 3
  32 +#define RMAbstractWebMapSourceDefaultWaitSeconds 15.0
33 33
34 @interface RMAbstractWebMapSource : RMAbstractMercatorTileSource 34 @interface RMAbstractWebMapSource : RMAbstractMercatorTileSource
35 35
  36 +@property (nonatomic, assign) NSUInteger retryCount;
  37 +@property (nonatomic, assign) NSTimeInterval waitSeconds;
  38 +
36 - (NSURL *)URLForTile:(RMTile)tile; 39 - (NSURL *)URLForTile:(RMTile)tile;
37 40
38 // Tilesources with layers use this method. 41 // Tilesources with layers use this method.
@@ -31,11 +31,16 @@ @@ -31,11 +31,16 @@
31 31
32 @implementation RMAbstractWebMapSource 32 @implementation RMAbstractWebMapSource
33 33
  34 +@synthesize retryCount, waitSeconds;
  35 +
34 - (id)init 36 - (id)init
35 { 37 {
36 if (!(self = [super init])) 38 if (!(self = [super init]))
37 return nil; 39 return nil;
38 - 40 +
  41 + self.retryCount = RMAbstractWebMapSourceDefaultRetryCount;
  42 + self.waitSeconds = RMAbstractWebMapSourceDefaultWaitSeconds;
  43 +
39 return self; 44 return self;
40 } 45 }
41 46
@@ -74,12 +79,12 @@ @@ -74,12 +79,12 @@
74 // 79 //
75 NSMutableArray *tilesData = [NSMutableArray arrayWithCapacity:[URLs count]]; 80 NSMutableArray *tilesData = [NSMutableArray arrayWithCapacity:[URLs count]];
76 81
77 - for (int p = 0; p < [URLs count]; p++) 82 + for (int p = 0; p < [URLs count]; ++p)
78 [tilesData addObject:[NSNull null]]; 83 [tilesData addObject:[NSNull null]];
79 84
80 dispatch_group_t fetchGroup = dispatch_group_create(); 85 dispatch_group_t fetchGroup = dispatch_group_create();
81 86
82 - for (int u = 0; u < [URLs count]; u++) 87 + for (int u = 0; u < [URLs count]; ++u)
83 { 88 {
84 NSURL *currentURL = [URLs objectAtIndex:u]; 89 NSURL *currentURL = [URLs objectAtIndex:u];
85 90
@@ -87,11 +92,11 @@ @@ -87,11 +92,11 @@
87 { 92 {
88 NSData *tileData = nil; 93 NSData *tileData = nil;
89 94
90 - for (int try = 0; try < RMAbstractWebMapSourceRetryCount; try++) 95 + for (int try = 0; tileData == nil && try < self.retryCount; ++try)
91 { 96 {
92 - if ( ! tileData)  
93 - // Beware: dataWithContentsOfURL is leaking like hell. Better use AFNetwork or ASIHTTPRequest  
94 - tileData = [NSData dataWithContentsOfURL:currentURL options:NSDataReadingUncached error:NULL]; 97 + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:currentURL];
  98 + [request setTimeoutInterval:(self.waitSeconds / (CGFloat)self.retryCount)];
  99 + tileData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
95 } 100 }
96 101
97 if (tileData) 102 if (tileData)
@@ -108,7 +113,7 @@ @@ -108,7 +113,7 @@
108 113
109 // wait for whole group of fetches (with retries) to finish, then clean up 114 // wait for whole group of fetches (with retries) to finish, then clean up
110 // 115 //
111 - dispatch_group_wait(fetchGroup, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * RMAbstractWebMapSourceWaitSeconds)); 116 + dispatch_group_wait(fetchGroup, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * self.waitSeconds));
112 dispatch_release(fetchGroup); 117 dispatch_release(fetchGroup);
113 118
114 // composite the collected images together 119 // composite the collected images together
@@ -463,7 +463,7 @@ @@ -463,7 +463,7 @@
463 } 463 }
464 464
465 averageX /= (double)enclosedAnnotationsCount; 465 averageX /= (double)enclosedAnnotationsCount;
466 - averageY /= (double) enclosedAnnotationsCount; 466 + averageY /= (double)enclosedAnnotationsCount;
467 467
468 double halfClusterMarkerWidth = clusterMarkerSize.width / 2.0, 468 double halfClusterMarkerWidth = clusterMarkerSize.width / 2.0,
469 halfClusterMarkerHeight = clusterMarkerSize.height / 2.0; 469 halfClusterMarkerHeight = clusterMarkerSize.height / 2.0;