-
Notifications
You must be signed in to change notification settings - Fork 2
/
SRRequestModel.m
333 lines (288 loc) · 14.9 KB
/
SRRequestModel.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
//
// SRRequestModel.m
// Soundrocket
//
// Created by Sebastian Boldt on 14.06.15.
// Copyright © 2015 sebastianboldt. All rights reserved.
//
#import "SRRequestModel.h"
#import "SRHelper.h"
#import "SoundrocketClient.h"
#import "SRAuthenticator.h"
#import "Track.h"
#import "SRFactory.h"
#import "URLParser.h"
#import <AFHTTPRequestOperationManager.h>
@interface SRRequestModel()
// Propertys for limit offset stuff
@property (nonatomic,strong) NSNumber * limit;
@property (nonatomic,strong) NSNumber * offset;
@property (nonatomic,strong) NSMutableArray * delegates;
@end
@implementation SRRequestModel
-(instancetype)init{
if (self = [super init]) {
// Basic values for RequestModel
self.nextUrl = nil;
self.endpoint = nil;
self.offset = @0;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.limit = @100;
} else {
self.limit = @30;
}
self.isLoading = NO;
self.itemsAvailable = YES;
self.results = [[NSMutableArray alloc]init];
self.delegates = SRCreateNonRetainingArray();
}
return self;
}
#pragma mark - Deleagte management
-(void)addDelegate:(id<SRRequestModelDelegate>)delegate{
if (![self.delegates containsObject:delegate]) {
[self.delegates addObject:delegate];
}
}
-(void)removeDelegate:(id)delegate{
if ([self.delegates containsObject:delegate]) {
[self.delegates removeObject:delegate];
}
}
-(void)refreshModel {
if (!self.isLoading) {
self.itemsAvailable = YES;
self.offset = @0;
self.nextUrl = nil;
}
}
-(NSURLSessionDataTask*)load {
__block __weak SRRequestModel * weakSelf = self;
if (self.itemsAvailable) {
self.isLoading = YES;
for (id<SRRequestModelDelegate> delegate in self.delegates) {
if ([delegate respondsToSelector:@selector(requestModelDidStartLoading:)]) {
[delegate requestModelDidStartLoading:self];
}
}
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSMutableDictionary * parameters = [[NSMutableDictionary alloc]init];
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
if ([SRAuthenticator sharedAuthenticator].authToken) {
[parameters setObject:[SRAuthenticator sharedAuthenticator].authToken forKey:@"oauth_token"];
} else {
[parameters setObject:[defaults objectForKey:@"access_token"] forKey:@"oauth_token"];
}
if (self.nextUrl != nil && ([self.nextUrl class] != [NSNull class])) {
// Setze die URL wenn nicht dann halt nicht
URLParser *parser = [[URLParser alloc] initWithURLString:self.nextUrl];
NSString * cursor = [parser valueForVariable:@"cursor"];
[parameters setObject:cursor forKey:@"cursor"];
} else {
[parameters setObject:self.limit forKey:@"limit"];
[parameters setObject:self.offset forKey:@"offset"];
}
NSString * nexturl = nil;
if (self.nextUrl != nil && ([self.nextUrl class] != [NSNull class])) {
nexturl = self.nextUrl;
} else {
nexturl = self.fetchURL;
}
if (self.additionalParameters) {
for (id key in [self.additionalParameters allKeys]) {
[parameters setObject:[self.additionalParameters objectForKey:key] forKey:key];
}
}
return [[SoundrocketClient sharedClient] GET:nexturl parameters:parameters
success: ^(NSURLSessionDataTask *task, id responseObject)
{
if (weakSelf.isRefreshing) {
self.results = [[NSMutableArray alloc]init];
weakSelf.isRefreshing = NO;
}
// Dictionary could be a next_href stuff
if ([responseObject isKindOfClass:[NSDictionary class]]) {
if ([responseObject objectForKey:@"next_href"]) {
self.nextUrl = [responseObject objectForKey:@"next_href"];
} else self.nextUrl = nil;
id object = nil;
if ([self.endpoint isEqualToString:SC_ACTIVITIES_ENDPOINT]) {
for (NSDictionary * activity in [responseObject objectForKey:@"collection"]) {
object = [SRFactory createObjectFromDictionary:activity];
if (object) {
[self.results addObject:object];
}
}
} else if([self.endpoint isEqualToString:SC_TRACKS_OF_PLAYLIST]){
if ([[responseObject objectForKey:@"tracks"]count] == 0) {
self.itemsAvailable = NO;
} else {
self.itemsAvailable = YES;
}
for (NSDictionary * trackInfo in [responseObject objectForKey:@"tracks"]) {
Track * track = [[Track alloc] initWithDictionary:trackInfo error:nil];
if (track) {
[self.results addObject:track];
}
}
} else if([self.endpoint isEqualToString:SC_FOLLOWERS_OF_USER] || [self.endpoint isEqualToString:SC_FOLLOWINGS_OF_USER]){
if ([[responseObject objectForKey:@"collection"]count] == 0) {
self.itemsAvailable = NO;
} else {
self.itemsAvailable = YES;
}
for (NSDictionary * userInfo in [responseObject objectForKey:@"collection"]) {
User * user = [[User alloc] initWithDictionary:userInfo error:nil];
if (user) {
[self.results addObject:user];
}
}
}
// If it is just an array it seems to use limit and offset
} else if ([responseObject isKindOfClass:[NSArray class]]){
if ([responseObject count] == 0) {
self.itemsAvailable = NO;
} else {
self.itemsAvailable = YES;
}
for (NSDictionary * trackInfo in responseObject) {
id object = nil;
// We know that likes are available
if ([self.endpoint isEqualToString:SC_LIKES_FAVORITES_ENDPOINT] ||[self.endpoint isEqualToString:SC_TRACKS_OF_USER] || [self.endpoint isEqualToString:SC_LIKES_OF_USER] || [self.endpoint isEqualToString:SC_SEARCH_TRACKS]) {
object = [SRFactory createTrackFromDictionary:trackInfo];
if (object) {
[self.results addObject:object];
}
} else if([self.endpoint isEqualToString:SC_PLAYLISTS_OF_USER] || [self.endpoint isEqualToString:SC_SEARCH_PLAYLISTS]){
object = [SRFactory createPlaylistFromDictionary:trackInfo];
if (object) {
[self.results addObject:object];
}
} else if([self.endpoint isEqualToString:SC_FOLLOWERS_OF_USER] || [self.endpoint isEqualToString:SC_FOLLOWINGS_OF_USER] || [self.endpoint isEqualToString:SC_SEARCH_USERS] || [self.endpoint isEqualToString:SC_FAVORITERS_OF_TRACK]){
object = [SRFactory createUserFromDictionary:trackInfo];
if (object) {
[self.results addObject:object];
}
} else if([self.endpoint isEqualToString:SC_COMMENTS_OF_TRACK]){
object = [SRFactory createCommentFromDictionary:trackInfo];
if (object) {
[self.results addObject:object];
}
}
}
}
long offset = [self.offset integerValue] + [self.limit integerValue];
self.offset = [NSNumber numberWithLong:offset];
self.isLoading = NO;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
// Inform the delegates
for (id<SRRequestModelDelegate> delegate in self.delegates) {
[delegate requestModelDidFinishLoading:weakSelf];
}
}
failure: ^(NSURLSessionDataTask *task, NSError *error)
{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
NSInteger statuscode = response.statusCode;
if (statuscode == 401) {
[[SRAuthenticator sharedAuthenticator]reauthenticateWithCompletion:^(){
[self load];
} failure:^(){
self.isLoading = NO;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
for (id<SRRequestModelDelegate> delegate in self.delegates) {
[delegate requestModelDidFailWithLoading:weakSelf withError:error];
}
}];
} else {
self.isLoading = NO;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
for (id<SRRequestModelDelegate> delegate in self.delegates) {
[delegate requestModelDidFailWithLoading:weakSelf withError:error];
}
}
}];
}
return nil;
}
// Sometimes the fetch url needs to be set manually
-(void)setEndpoint:(NSString *)endpoint {
[self refreshModel];
if (_endpoint != endpoint) {
_endpoint = endpoint;
if ([_endpoint isEqualToString:SC_LIKES_FAVORITES_ENDPOINT]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/favorites.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
} else if([_endpoint isEqualToString:SC_ACTIVITIES_ENDPOINT]) {
self.fetchURL = @"https://api.soundcloud.com/me/activities.json";
} else if([_endpoint isEqualToString:SC_FAVORITERS_OF_TRACK]) {
if ([self.inlineURLParameter objectForKey:@"track_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/tracks/%@/favoriters.json",[self.inlineURLParameter objectForKey:@"track_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/tracks/%@/favoriters.json",@0];
}
}
else if([_endpoint isEqualToString:SC_SEARCH_PLAYLISTS]) {
self.fetchURL = @"https://api.soundcloud.com/playlists.json";
} else if([_endpoint isEqualToString:SC_SEARCH_TRACKS]) {
self.fetchURL = @"https://api.soundcloud.com/tracks.json";
} else if([_endpoint isEqualToString:SC_SEARCH_USERS]) {
self.fetchURL = @"https://api.soundcloud.com/users.json";
} else if ([endpoint isEqualToString:SC_COMMENTS_OF_TRACK]){
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/tracks/%@/comments.json?order=created_at",[self.inlineURLParameter objectForKey:@"track_id"]];
}
// User Profile
else if([_endpoint isEqualToString:SC_PLAYLISTS_OF_USER]) {
if ([self.inlineURLParameter objectForKey:@"user_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/playlists.json",[self.inlineURLParameter objectForKey:@"user_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/playlists.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
}
}
else if([_endpoint isEqualToString:SC_LIKES_OF_USER]) {
if ([self.inlineURLParameter objectForKey:@"user_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/favorites.json",[self.inlineURLParameter objectForKey:@"user_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/favorites.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
}
}
else if([_endpoint isEqualToString:SC_TRACKS_OF_USER]) {
if ([self.inlineURLParameter objectForKey:@"user_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/tracks.json",[self.inlineURLParameter objectForKey:@"user_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/tracks.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
}
}
else if([_endpoint isEqualToString:SC_FOLLOWERS_OF_USER]) {
if ([self.inlineURLParameter objectForKey:@"user_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/followers.json",[self.inlineURLParameter objectForKey:@"user_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/followers.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
}
}
else if([_endpoint isEqualToString:SC_FOLLOWINGS_OF_USER]) {
if ([self.inlineURLParameter objectForKey:@"user_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/followings.json",[self.inlineURLParameter objectForKey:@"user_id"]];
} else {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/users/%@/followings.json",[SRAuthenticator sharedAuthenticator].currentUser.id];
}
}
else if([_endpoint isEqualToString:SC_TRACKS_OF_PLAYLIST]) {
if ([self.inlineURLParameter objectForKey:@"playlist_id"]) {
self.fetchURL = [NSString stringWithFormat:@"https://api.soundcloud.com/playlists/%@.json",[self.inlineURLParameter objectForKey:@"playlist_id"]];
}
}
}
}
-(NSMutableArray *)justTracksAndReposts {
NSMutableArray * tracksAndReposts = [[NSMutableArray alloc]init];
for (id object in self.results) {
if ([object isKindOfClass:[Track class]] || [object isKindOfClass:[TrackRepost class]]) {
[tracksAndReposts addObject:object];
}
}
return tracksAndReposts;
}
-(void)setInlineURLParameter:(NSDictionary *)inlineURLParameter {
_inlineURLParameter = inlineURLParameter;
}
@end