samhuri.net-ios/Blog/BlogService.m

124 lines
4.2 KiB
Objective-C

//
// BlogService.m
// Blog
//
// Created by Sami Samhuri on 2014-11-23.
// Copyright (c) 2014 Guru Logic Inc. All rights reserved.
//
#import "BlogService.h"
#import <Mantle/MTLJSONAdapter.h>
#import "NSString+marshmallows.h"
#import "JSONHTTPClient.h"
#import "BlogStatus.h"
#import "Post.h"
NSString *const BlogServiceErrorDomain = @"BlogServiceErrorDomain";
@interface BlogService ()
@property (nonatomic, readonly, strong) NSString *rootURL;
@property (nonatomic, readonly, strong) JSONHTTPClient *client;
@end
@implementation BlogService
- (instancetype)initWithRootURL:(NSString *)rootURL client:(JSONHTTPClient *)client {
NSParameterAssert([rootURL length]);
NSParameterAssert(client);
self = [super init];
_rootURL = [rootURL mm_stringByReplacing:@"/$" with:@""];
_client = client;
return self;
}
- (NSURL *)urlFor:(NSString *)path, ... {
va_list args;
va_start(args, path);
path = [[NSString alloc] initWithFormat:path arguments:args];
va_end(args);
NSString *slash = [path hasPrefix:@"/"] ? @"" : @"/";
NSString *urlString = [self.rootURL stringByAppendingFormat:@"%@%@", slash, path];
NSURL *url = [NSURL URLWithString:urlString];
if (!url) {
@throw [NSException exceptionWithName:@"BlogServiceException" reason:@"Invalid URL" userInfo:@{@"URL": urlString ?: [NSNull null]}];
}
return url;
}
- (id (^)(NSDictionary *))decodePostBlock {
return ^(NSDictionary *root) {
NSError *error = nil;
Post *post = [MTLJSONAdapter modelOfClass:[Post class] fromJSONDictionary:root[@"post"] error:&error];
return post ?: error;
};
}
- (id (^)(NSDictionary *))decodePostsBlock {
return ^(NSDictionary *root) {
NSError *error = nil;
NSArray *posts = [MTLJSONAdapter modelsOfClass:[Post class] fromJSONArray:root[@"posts"] error:&error];
return posts ?: error;
};
}
- (PMKPromise *)requestBlogStatus {
return [self.client get:[self urlFor:@"/status"] headers:nil].then(^(NSDictionary *root) {
NSError *error = nil;
BlogStatus *status = [MTLJSONAdapter modelOfClass:[BlogStatus class] fromJSONDictionary:root[@"status"] error:&error];
return status ?: error;
});
}
- (PMKPromise *)requestPublishEnvironment:(NSString *)environment {
NSDictionary *fields = @{@"env": environment ?: @"staging"};
return [self.client postJSON:[self urlFor:@"/publish"] headers:nil fields:fields];
}
- (PMKPromise *)requestDrafts {
return [self.client get:[self urlFor:@"/posts/drafts"] headers:nil].then([self decodePostsBlock]);
}
- (PMKPromise *)requestPublishedPosts {
return [self.client get:[self urlFor:@"/posts"] headers:nil].then([self decodePostsBlock]);
}
- (PMKPromise *)requestPostWithPath:(NSString *)path {
return [self.client get:[self urlFor:path] headers:nil].then([self decodePostBlock]);
}
- (PMKPromise *)requestCreateDraftWithID:(NSString *)draftID title:(NSString *)title body:(NSString *)body link:(NSString *)link publish:(BOOL)publish {
NSDictionary *fields = @{
@"id" : draftID,
@"title" : title ?: [NSNull null],
@"body" : body,
@"link" : link ?: [NSNull null],
@"publish" : publish ? @"true" : [NSNull null],
};
return [self.client postJSON:[self urlFor:@"/posts/drafts"] headers:nil fields:fields].then([self decodePostBlock]);
}
- (PMKPromise *)requestPublishDraftWithPath:(NSString *)path {
return [self.client post:[self urlFor:@"%@/publish", path] headers:nil].then([self decodePostBlock]);
}
- (PMKPromise *)requestUnpublishPostWithPath:(NSString *)path {
return [self.client post:[self urlFor:@"%@/unpublish", path] headers:nil].then([self decodePostBlock]);
}
- (PMKPromise *)requestUpdatePostWithPath:(NSString *)path title:(NSString *)title body:(NSString *)body link:(NSString *)link {
NSDictionary *fields = @{
@"title" : title ?: [NSNull null],
@"body" : body,
@"link" : link ?: [NSNull null],
};
return [self.client putJSON:[self urlFor:path] headers:nil fields:fields];
}
- (PMKPromise *)requestDeletePostWithPath:(NSString *)path {
return [self.client delete:[self urlFor:path] headers:nil];
}
@end