Untested version of wrapper code. Needs testing and documentation.
authorJonathan Williamson <jonathan.williamson@hedgehoglab.com>
Tue Dec 22 13:23:36 2009 +0000
changeset 07ec1e6dc1a5a
child 1 4d7a9ee3c174
Untested version of wrapper code. Needs testing and documentation.
fixxApiObjectMapper.h
fixxApiObjectMapper.m
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/fixxApiObjectMapper.h	Tue Dec 22 13:23:36 2009 +0000
     1.3 @@ -0,0 +1,129 @@
     1.4 +//
     1.5 +//  fixxApiObjectMapper.h
     1.6 +//  fixx
     1.7 +//
     1.8 +//  Created by Jonathan Williamson on 26/11/2009.
     1.9 +//  Copyright 2009 Hedgehog Lab. All rights reserved.
    1.10 +//
    1.11 +
    1.12 +#import <Foundation/Foundation.h>
    1.13 +
    1.14 +@interface fixxApiObjectMapper : NSObject
    1.15 +{
    1.16 +@private
    1.17 +	NSString *username;
    1.18 +	NSString *password;
    1.19 +	NSString *url;
    1.20 +}
    1.21 +
    1.22 +- (id)initWithUsername: (NSString *)_username password: (NSString *)_password andUrl: (NSString *)_url;
    1.23 +
    1.24 +// Generic request methods
    1.25 +// -----------------------
    1.26 +
    1.27 +// GET
    1.28 +- (id) requestObjectForApiExtension: (NSString *)extention;
    1.29 +- (id) requestObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids;
    1.30 +
    1.31 +// POST and PUT
    1.32 +- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andRequestMethod: (NSString *)method;
    1.33 +- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andIds: (NSArray *)Ids andRequestMethod: (NSString *)method;
    1.34 +
    1.35 +// DELETE
    1.36 +- (id) deleteObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids;
    1.37 +
    1.38 +
    1.39 +// Projects
    1.40 +// --------
    1.41 +
    1.42 +- (NSMutableArray *)getAllProjects;
    1.43 +- (NSMutableDictionary *)getProjectWithId: (NSInteger)ID;
    1.44 +
    1.45 +- (NSInteger)createProjectFromObject: (NSMutableDictionary *)object;
    1.46 +
    1.47 +- (NSInteger)updateProjectFromObject: (NSMutableDictionary *)object;
    1.48 +
    1.49 +
    1.50 +// Resolutions
    1.51 +// -----------
    1.52 +
    1.53 +- (NSMutableArray *)getAllResolutionsForProjectWithId: (NSInteger)ID;
    1.54 +- (NSMutableArray *)getAllIssueTypesForProjectWithId: (NSInteger)ID;
    1.55 +
    1.56 +
    1.57 +// Areas
    1.58 +// -----
    1.59 +
    1.60 +- (NSMutableArray *)getAllVersionsForProjectWithId: (NSInteger)ID;
    1.61 +- (NSMutableArray *)getReleasedVersionsForProjectWithId: (NSInteger)ID;
    1.62 +
    1.63 +
    1.64 +// Issues
    1.65 +// ------
    1.66 +
    1.67 +- (NSMutableArray *)getAllIssuesForProjectWithId: (NSInteger)ID;
    1.68 +- (NSMutableArray *)getAllIssuesWithQuerystrings: (NSArray *)strings;
    1.69 +- (NSMutableDictionary *)getIssueWithId: (NSInteger)ID;
    1.70 +
    1.71 +- (NSInteger)createIssueFromObject: (NSMutableDictionary *)object;
    1.72 +
    1.73 +- (NSInteger)updateIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object;
    1.74 +
    1.75 +
    1.76 +// Comments
    1.77 +// --------
    1.78 +
    1.79 +- (NSMutableArray *)getAllCommentsForIssueWithId: (NSInteger)ID;
    1.80 +
    1.81 +- (NSInteger)addCommentToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object;
    1.82 +
    1.83 +- (NSInteger)deleteCommentWithId: (NSInteger)commentId fromIssueWithId: (NSInteger)issueId;
    1.84 +
    1.85 +
    1.86 +// Timelogs
    1.87 +// --------
    1.88 +
    1.89 +- (NSMutableDictionary *)getAllTimelogsForIssueWithId: (NSInteger)ID;
    1.90 +
    1.91 +- (NSInteger)addTimelogToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object;
    1.92 +
    1.93 +- (NSInteger)deleteTimelogWithId: (NSInteger)timelogId fromIssueWithId: (NSInteger)issueId;
    1.94 +
    1.95 +
    1.96 +// Tags
    1.97 +// ----
    1.98 +
    1.99 +- (NSMutableArray *)getAllTagsForIssueWithId: (NSInteger)ID;
   1.100 +
   1.101 +- (NSInteger)addTagToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object;
   1.102 +
   1.103 +- (NSInteger)deleteTagWithId: (NSInteger)tagId fromIssueWithId: (NSInteger)issueId;
   1.104 +
   1.105 +
   1.106 +// Changelogs
   1.107 +// ----------
   1.108 +
   1.109 +- (NSMutableArray *)getAllChangelogsForIssueWithId: (NSInteger)ID;
   1.110 +
   1.111 +
   1.112 +// Users
   1.113 +// -----
   1.114 +
   1.115 +- (NSMutableArray *)getAllUsers;
   1.116 +
   1.117 +- (NSMutableDictionary *)getUserWithId: (NSInteger)ID;
   1.118 +- (NSMutableDictionary *)getUserWithUsername: (NSString *)username;
   1.119 +- (NSMutableArray *)getUsersForProjectWithId: (NSInteger)ID;
   1.120 +- (NSMutableArray *)getClientsForProjectWithId: (NSInteger)ID;
   1.121 +- (NSMutableArray *)getUsersWatchingIssueWithId: (NSInteger)ID;
   1.122 +- (NSMutableArray *)substribeUserWithId: (NSInteger)userId toIssueWithId: (NSInteger)issueId;
   1.123 +
   1.124 +
   1.125 +// Priorities
   1.126 +// ----------
   1.127 +
   1.128 +- (NSMutableArray *) getAllPriorities;
   1.129 +- (NSMutableDictionary *) getPriorityWithId: (NSInteger)ID;
   1.130 +
   1.131 +
   1.132 +@end
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/fixxApiObjectMapper.m	Tue Dec 22 13:23:36 2009 +0000
     2.3 @@ -0,0 +1,437 @@
     2.4 +//
     2.5 +//  fixxApiObjectMapper.m
     2.6 +//  fixx
     2.7 +//
     2.8 +//  Created by Jonathan Williamson on 26/11/2009.
     2.9 +//  Copyright 2009 Hedgehog Lab. All rights reserved.
    2.10 +//
    2.11 +
    2.12 +#import "fixxApiObjectMapper.h"
    2.13 +#import "ASIHTTPRequest.h"
    2.14 +#import "JSON.h"
    2.15 +
    2.16 +@implementation fixxApiObjectMapper
    2.17 +
    2.18 +//******************************************
    2.19 +
    2.20 +- (id)initWithUsername: (NSString *)_username password: (NSString *)_password andUrl: (NSString *)_url
    2.21 +{
    2.22 +	username = [NSString stringWithString:_username];
    2.23 +	password = [NSString stringWithString:_password];
    2.24 +	url = [NSString stringWithString:_url];
    2.25 +	
    2.26 +	return self;
    2.27 +}
    2.28 +
    2.29 +//******************************************
    2.30 +
    2.31 +- (id) requestObjectForApiExtension: (NSString *)extention
    2.32 +{	
    2.33 +	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
    2.34 +	
    2.35 +	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
    2.36 +	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
    2.37 +	[myRequest setUsername:username];
    2.38 +	[myRequest setPassword:password];
    2.39 +	
    2.40 +	NSString *authInfo = [NSString stringWithString:@"Basic "];
    2.41 +	authInfo = [authInfo stringByAppendingString: username];
    2.42 +	authInfo = [authInfo stringByAppendingString:@":"];
    2.43 +	authInfo = [authInfo stringByAppendingString:password];
    2.44 +	
    2.45 +	[myRequest addRequestHeader:@"Authorization" value:authInfo];
    2.46 +	
    2.47 +	[myRequest start];
    2.48 +	
    2.49 +	SBJsonParser *jsonParser = [SBJsonParser new];
    2.50 +	id objectData = nil;
    2.51 +	if([myRequest responseStatusCode] == 200)
    2.52 +		objectData = [[jsonParser objectWithString: myRequest.responseString] retain];
    2.53 +	
    2.54 +	[jsonParser release];
    2.55 +	
    2.56 +	return objectData;
    2.57 +}
    2.58 +
    2.59 +//******************************************
    2.60 +
    2.61 +- (id) requestObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids
    2.62 +{
    2.63 +	int hashCount = 0;
    2.64 +	for(int i=0; i<[extention length]; ++i)
    2.65 +		if([extention characterAtIndex:i] == '#') ++hashCount;
    2.66 +	
    2.67 +	if(hashCount != [Ids count]) return nil;
    2.68 +		
    2.69 +	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
    2.70 +		
    2.71 +	NSInteger count = 1;
    2.72 +	for(NSNumber *ID in Ids)
    2.73 +	{
    2.74 +		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
    2.75 +		++count;
    2.76 +	}
    2.77 +	
    2.78 +	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
    2.79 +	
    2.80 +	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
    2.81 +	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
    2.82 +	[myRequest setUsername:username];
    2.83 +	[myRequest setPassword:password];
    2.84 +	
    2.85 +	NSString *authInfo = [NSString stringWithString:@"Basic "];
    2.86 +	authInfo = [authInfo stringByAppendingString: username];
    2.87 +	authInfo = [authInfo stringByAppendingString:@":"];
    2.88 +	authInfo = [authInfo stringByAppendingString:password];
    2.89 +	
    2.90 +	[myRequest addRequestHeader:@"Authorization" value:authInfo];
    2.91 +	
    2.92 +	[myRequest start];
    2.93 +	
    2.94 +	SBJsonParser *jsonParser = [SBJsonParser new];
    2.95 +	id objectData = nil;
    2.96 +	if([myRequest responseStatusCode] == 200) objectData = [[jsonParser objectWithString: myRequest.responseString] retain];
    2.97 +	
    2.98 +	[jsonParser release];
    2.99 +	
   2.100 +	return objectData;
   2.101 +}
   2.102 +
   2.103 +//******************************************
   2.104 +
   2.105 +- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andRequestMethod: (NSString *)method
   2.106 +{	
   2.107 +	if(![method isEqualToString:@"POST"] && ![method isEqualToString:@"PUT"]) return -1;
   2.108 +	
   2.109 +	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
   2.110 +	
   2.111 +	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
   2.112 +	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
   2.113 +	[myRequest setUsername:username];
   2.114 +	[myRequest setPassword:password];
   2.115 +	
   2.116 +	NSString *authInfo = [NSString stringWithString:@"Basic "];
   2.117 +	authInfo = [authInfo stringByAppendingString: username];
   2.118 +	authInfo = [authInfo stringByAppendingString:@":"];
   2.119 +	authInfo = [authInfo stringByAppendingString:password];
   2.120 +	
   2.121 +	SBJsonWriter *jsonWriter = [SBJsonWriter new];
   2.122 +	
   2.123 +	[myRequest addRequestHeader:@"Authorization" value:authInfo];
   2.124 +	NSString *postData = [jsonWriter stringWithObject:object];
   2.125 +	[myRequest appendPostData: [postData dataUsingEncoding:NSUTF8StringEncoding]];
   2.126 +	[myRequest setRequestMethod: method];
   2.127 +	
   2.128 +	[myRequest start];
   2.129 +	 
   2.130 +	[jsonWriter release];
   2.131 +	
   2.132 +	return [myRequest responseStatusCode];
   2.133 +}
   2.134 +
   2.135 +//******************************************
   2.136 +
   2.137 +- (NSInteger) sendObject: (NSMutableDictionary *)object forApiExtension: (NSString *)extention andIds: (NSArray *)Ids andRequestMethod: (NSString *)method
   2.138 +{
   2.139 +	if(![method isEqualToString:@"POST"] && ![method isEqualToString:@"PUT"]) return -1;
   2.140 +	
   2.141 +	int hashCount = 0;
   2.142 +	for(int i=0; i<[extention length]; ++i)
   2.143 +		if([extention characterAtIndex:i] == '#') ++hashCount;
   2.144 +	
   2.145 +	if(hashCount != [Ids count]) return nil;
   2.146 +	
   2.147 +	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
   2.148 +	
   2.149 +	NSInteger count = 1;
   2.150 +	for(NSNumber *ID in Ids)
   2.151 +	{
   2.152 +		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
   2.153 +		++count;
   2.154 +	}
   2.155 +	
   2.156 +	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
   2.157 +	
   2.158 +	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
   2.159 +	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
   2.160 +	[myRequest setUsername:username];
   2.161 +	[myRequest setPassword:password];
   2.162 +	
   2.163 +	NSString *authInfo = [NSString stringWithString:@"Basic "];
   2.164 +	authInfo = [authInfo stringByAppendingString: username];
   2.165 +	authInfo = [authInfo stringByAppendingString:@":"];
   2.166 +	authInfo = [authInfo stringByAppendingString:password];
   2.167 +	
   2.168 +	SBJsonWriter *jsonWriter = [SBJsonWriter new];
   2.169 +	
   2.170 +	[myRequest addRequestHeader:@"Authorization" value:authInfo];
   2.171 +	NSString *postData = [jsonWriter stringWithObject:object];
   2.172 +	[myRequest appendPostData: [postData dataUsingEncoding:NSUTF8StringEncoding]];
   2.173 +	[myRequest setRequestMethod: method];
   2.174 +	
   2.175 +	[myRequest start];
   2.176 +	
   2.177 +	[jsonWriter release];
   2.178 +	
   2.179 +	return [myRequest responseStatusCode];
   2.180 +}
   2.181 +
   2.182 +//******************************************
   2.183 +
   2.184 +- (id) deleteObjectForApiExtension: (NSString *)extention andIds: (NSArray *)Ids
   2.185 +{
   2.186 +	int hashCount = 0;
   2.187 +	for(int i=0; i<[extention length]; ++i)
   2.188 +		if([extention characterAtIndex:i] == '#') ++hashCount;
   2.189 +	
   2.190 +	if(hashCount != [Ids count]) return nil;
   2.191 +	
   2.192 +	NSString *tempUrl = [NSString stringWithString:[url stringByAppendingString:extention]];
   2.193 +	
   2.194 +	NSInteger count = 1;
   2.195 +	for(NSNumber *ID in Ids)
   2.196 +	{
   2.197 +		tempUrl = [tempUrl stringByReplacingOccurrencesOfString:[@"#" stringByAppendingString:[[NSNumber numberWithInt:count] stringValue]] withString:[ID stringValue]];
   2.198 +		++count;
   2.199 +	}
   2.200 +	
   2.201 +	ASIHTTPRequest *myRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAppendingString:extention]]];
   2.202 +	
   2.203 +	[myRequest addRequestHeader:@"Accept" value:@"application/json"];
   2.204 +	[myRequest addRequestHeader:@"Content-Type" value:@"application/json"];
   2.205 +	[myRequest setUsername:username];
   2.206 +	[myRequest setPassword:password];
   2.207 +	
   2.208 +	NSString *authInfo = [NSString stringWithString:@"Basic "];
   2.209 +	authInfo = [authInfo stringByAppendingString: username];
   2.210 +	authInfo = [authInfo stringByAppendingString:@":"];
   2.211 +	authInfo = [authInfo stringByAppendingString:password];
   2.212 +	
   2.213 +	[myRequest addRequestHeader:@"Authorization" value:authInfo];
   2.214 +	[myRequest requestMethod:@"DELETE"];
   2.215 +	
   2.216 +	[myRequest start];
   2.217 +	
   2.218 +	return [myRequest responseStatusCode];
   2.219 +}
   2.220 +
   2.221 +//******************************************
   2.222 +
   2.223 +// Projects
   2.224 +// --------
   2.225 +- (NSMutableArray *)getAllProjects
   2.226 +{
   2.227 +	return [self requestObjectForApiExtension:@"api/projects"];
   2.228 +}
   2.229 +
   2.230 +- (NSMutableDictionary *)getProjectWithId: (NSInteger)ID
   2.231 +{
   2.232 +	return [self requestObjectForApiExtension:@"api/projects/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.233 +}
   2.234 +
   2.235 +- (NSInteger)createProjectFromObject: (NSMutableDictionary *)object
   2.236 +{
   2.237 +	return [self sendObject:object forApiExtension:@"api/projects" andRequestMethod:@"POST"];
   2.238 +}
   2.239 +
   2.240 +- (NSInteger)updateProject: (NSInteger)ID fromObject: (NSMutableDictionary *)object
   2.241 +{
   2.242 +	return [self sendObject:object forApiExtension:@"api/projects/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"PUT"];
   2.243 +}
   2.244 +
   2.245 +
   2.246 +// Resolutions
   2.247 +// -----------
   2.248 +
   2.249 +- (NSMutableArray *)getAllResolutionsForProjectWithId: (NSInteger)ID
   2.250 +{
   2.251 +	return [self requestObjectForApiExtension:@"api/projects/#1/resolutions" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.252 +}
   2.253 +
   2.254 +- (NSMutableArray *)getAllIssueTypesForProjectWithId: (NSInteger)ID
   2.255 +{
   2.256 +	return [self requestObjectForApiExtension:@"api/projects/#1/issue-types" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.257 +}
   2.258 +
   2.259 +
   2.260 +// Areas
   2.261 +// -----
   2.262 +
   2.263 +- (NSMutableArray *)getAllAreasForProjectWithId: (NSInteger)ID
   2.264 +{
   2.265 +	return [self requestObjectForApiExtension:@"api/projects/#1/areas" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.266 +}
   2.267 +
   2.268 +- (NSMutableArray *)getAllVersionsForProjectWithId: (NSInteger)ID
   2.269 +{
   2.270 +	return [self requestObjectForApiExtension:@"api/projects/#1/versions" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.271 +}
   2.272 +
   2.273 +- (NSMutableArray *)getReleasedVersionsForProjectWithId: (NSInteger)ID
   2.274 +{
   2.275 +	return [self requestObjectForApiExtension:@"api/projects/#1/versions?type=fixfor" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.276 +}
   2.277 +
   2.278 +
   2.279 +// Issues
   2.280 +// ------
   2.281 +
   2.282 +- (NSMutableArray *)getAllIssuesForProjectWithId: (NSInteger)ID
   2.283 +{
   2.284 +	return [self requestObjectForApiExtension:@"api/projects/#1/issues" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.285 +}
   2.286 +
   2.287 +- (NSMutableArray *)getAllIssuesWithQuerystrings: (NSArray *)strings
   2.288 +{
   2.289 +	NSString *temp = [NSString stringWithString:@"api/issues?"];
   2.290 +	for(NSString *string in strings)
   2.291 +	{
   2.292 +		temp = [temp stringByAppendingString:string];
   2.293 +		temp = [temp stringByAppendingString:@"&"];
   2.294 +	}
   2.295 +	temp = [temp substringToIndex:([temp length]-2)];
   2.296 +	
   2.297 +	return [self requestObjectForApiExtension:temp];
   2.298 +}
   2.299 +
   2.300 +- (NSMutableDictionary *)getIssueWithId: (NSInteger)ID
   2.301 +{
   2.302 +	return [self requestObjectForApiExtension:@"/api/issues/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.303 +}
   2.304 +
   2.305 +- (NSInteger)createIssueFromObject: (NSMutableDictionary *)object
   2.306 +{
   2.307 +	return [self sendObject:object forApiExtension:@"api/issues" andRequestMethod:@"POST"];
   2.308 +}
   2.309 +
   2.310 +- (NSInteger)updateIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
   2.311 +{
   2.312 +	return [self sendObject:object forApiExtension:@"api/issues/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"PUT"];
   2.313 +}
   2.314 +
   2.315 +
   2.316 +// Comments
   2.317 +// --------
   2.318 +
   2.319 +- (NSMutableArray *)getAllCommentsForIssueWithId: (NSInteger)ID
   2.320 +{
   2.321 +	return [self requestObjectForApiExtension:@"api/issues/#1/comments" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.322 +}
   2.323 +
   2.324 +- (NSInteger)addCommentToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
   2.325 +{
   2.326 +	return [self sendObject:object forApiExtension:@"api/issues/#1/comments" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
   2.327 +}
   2.328 +
   2.329 +- (NSInteger)deleteCommentWithId: (NSInteger)commentId fromIssueWithId: (NSInteger)issueId
   2.330 +{
   2.331 +	[self deleteObjectForApiExtension: @"api/issues/#1/comments/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:commentId], nil]];
   2.332 +}
   2.333 +
   2.334 +
   2.335 +// Timelogs
   2.336 +// --------
   2.337 +
   2.338 +- (NSMutableDictionary *)getAllTimelogsForIssueWithId: (NSInteger)ID
   2.339 +{
   2.340 +	return [self requestObjectForApiExtension:@"api/issues/#1/timelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.341 +}
   2.342 +
   2.343 +- (NSInteger)addTimelogToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
   2.344 +{
   2.345 +	return [self sendObject:object forApiExtension:@"api/issues/#1/timelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
   2.346 +}
   2.347 +
   2.348 +- (NSInteger)deleteTimelogWithId: (NSInteger)timelogId fromIssueWithId: (NSInteger)issueId
   2.349 +{
   2.350 +	[self deleteObjectForApiExtension: @"api/issues/#1/timelogs/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:timelogId], nil]];
   2.351 +}
   2.352 +
   2.353 +
   2.354 +// Tags
   2.355 +// ----
   2.356 +
   2.357 +- (NSMutableArray *)getAllTagsForIssueWithId: (NSInteger)ID
   2.358 +{
   2.359 +	return [self requestObjectForApiExtension:@"api/issues/#1/tags" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.360 +}
   2.361 +
   2.362 +- (NSInteger)addTagToIssueWithId: (NSInteger)ID fromObject: (NSMutableDictionary *)object
   2.363 +{
   2.364 +	return [self sendObject:object forApiExtension:@"api/issues/#1/tags" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil] andRequestMethod:@"POST"];
   2.365 +}
   2.366 +
   2.367 +- (NSInteger)deleteTagWithId: (NSInteger)tagId fromIssueWithId: (NSInteger)issueId
   2.368 +{
   2.369 +	[self deleteObjectForApiExtension: @"api/issues/#1/tags/#2" andIds: [NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:tagId], nil]];
   2.370 +}
   2.371 +
   2.372 +// Changelogs
   2.373 +// ----------
   2.374 +
   2.375 +- (NSMutableArray *)getAllChangelogsForIssueWithId: (NSInteger)ID
   2.376 +{
   2.377 +	return [self requestObjectForApiExtension:@"api/issues/#1/changelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.378 +}
   2.379 +
   2.380 +
   2.381 +// Users
   2.382 +// -----
   2.383 +
   2.384 +- (NSMutableArray *)getAllUsers
   2.385 +{
   2.386 +	return [self requestObjectForApiExtension:@"api/users"];
   2.387 +}
   2.388 +
   2.389 +- (NSMutableDictionary *)getUserWithId: (NSInteger)ID
   2.390 +{
   2.391 +	return [self requestObjectForApiExtension:@"api/issues/#1/changelogs" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.392 +}
   2.393 +
   2.394 +- (NSMutableDictionary *)getUserWithUsername: (NSString *)_username
   2.395 +{
   2.396 +	return [self requestObjectForApiExtension:[@"api/users/" stringByAppendingString:_username]];
   2.397 +}
   2.398 +
   2.399 +- (NSMutableArray *)getUsersForProjectWithId: (NSInteger)ID
   2.400 +{
   2.401 +	return [self requestObjectForApiExtension:@"api/projects/#1/users" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.402 +}
   2.403 +
   2.404 +- (NSMutableArray *)getClientsForProjectWithId: (NSInteger)ID
   2.405 +{
   2.406 +	return [self requestObjectForApiExtension:@"api/projects/#1/clients" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.407 +}
   2.408 +
   2.409 +- (NSMutableArray *)getUsersWatchingIssueWithId: (NSInteger)ID
   2.410 +{
   2.411 +	return [self requestObjectForApiExtension:@"api/issues/#1/watchers" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.412 +}
   2.413 +
   2.414 +- (NSInteger)subscribeUserWithId: (NSInteger)userId toIssueWithId: (NSInteger)issueId
   2.415 +{
   2.416 +	//return [self sendObject:nil forApiExtension:@"api/issues/#1/watchers/#2" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:issueId], [NSNumber numberWithInt:userId], nil] andRequestMethod:@"PUT"];
   2.417 +	//Wierd!
   2.418 +	return 0;
   2.419 +}
   2.420 +
   2.421 +
   2.422 +// Priorities
   2.423 +// ----------
   2.424 +
   2.425 +- (NSMutableArray *) getAllPriorities
   2.426 +{
   2.427 +	return [self requestObjectForApiExtension:@"api/priorities"];
   2.428 +}
   2.429 +
   2.430 +- (NSMutableDictionary *) getPriorityWithId: (NSInteger)ID
   2.431 +{
   2.432 +	return [self requestObjectForApiExtension:@"api/priorities/#1" andIds:[NSArray arrayWithObjects:[NSNumber numberWithInt:ID], nil]];
   2.433 +}
   2.434 +
   2.435 +- (void) dealloc
   2.436 +{
   2.437 +	[super dealloc];
   2.438 +}
   2.439 +
   2.440 +@end