Latest 4.0.0-b01
Homepage https://github.com/byss/KBAPISupport
License MIT
Platforms ios 10.0, tvos 10.0, osx 10.12, watchos 4.0
Frameworks Foundation
Authors

This mini-library is used to access various types of HTTP-based APIs.

License

The library itself is licensed under MIT License; GDataXML is licensed under Apache License. If you use this library in an application and notify me about it, i would be pleased :)

Features

  • Support for GET/POST/PUT/DELETE HTTP requests.
  • This library uses GDataXML for XML parsing, its sources are already included in library. GDataXML depends only on standart libxml2 headers and binary library. By the way, GDataXML uses non-ARC environment, so you should set compile flag -fno-objc-arc for GDataXMLNode.m file.
  • This library uses NSJSONSerialization for JSON parsing by default, so iOS 5.0+ is supported. You may use SBJson aka json-framework, though (get it here), but this library was only tested with NSJSONSerialization.
  • Autoconstructing objects from JSON/XML using AutoObjects.
  • This library is suitable for ARC- and non-ARC projects (AutoObjects are supported only in non-ARC environment). The author is not quite familliar with ARC mode though so feel free to enchance nasty pieces of code.

Config

There is main header file called KBAPISupport.h, where all other headers are #imported. Amongst other, there is KBAPISupport-config.h, where all configuration is done:

  • #define KBAPISUPPORT_DEBUG 0

    Turns on and off internal debug messages.

  • #define KBAPISUPPORT_JSON 1

    Turns on and off support for server JSON responses.

  • #define KBAPISUPPORT_USE_SBJSON 0

    If you need to use this library on iOS 4.3 and older then you need to use SBJson library. Otherwise, you should use NSJSONSerialization, because it works faster and consumes less RAM (see e. g. this blog post).

  • #define KBAPISUPPORT_XML 1

    You should enable this option if you want to parse XML server responses. Depends on GDataXMLNode.h.

  • #define KBAPISUPPORT_DECODE 0

    By default all parsers assume that server encoding is set to UTF-8. If this it not applicable then enable this option.

  • #define KBAPISUPPORT_DECODE_FROM (NSWindowsCP1251StringEncoding)

    It has effect only if KBAPISUPPORT_DECODE is nonzero. Set the server encoding here to convert responses to Apple’s Unicode.

Including library into your project

  • Import the library project as subproject: right-click on desired project group, then select KBAPISupport.xcodeproj.

  • Add the library to your target dependencies: select your project in the left pane, select your target, select ‘Build Phases’ tab, expand ‘Target Dependencies’ and click "plus" sign.

  • If you are using XML, then you should append -ObjC to your linker flags. Open build settings of your target, locate ‘Other Linker Flags’ option in ‘Linking’ section and add -ObjC to the value of the option.

  • You may also need to add library headers to search path. To achieve this, select ‘Build Settings’ tab, find ‘Search Paths’ section and append appropriate search path to ‘Header Search Path’ array.

Usage

  • #import "KBAPISupport.h"

    This would import all KBAPISupport features, excluding GDataXMLElement category and debug macros. Suitable for including in prefix precompiled header. You may also #import single header files.

  • KBAPISupport doesn’t provide any API interfaces by itself, you should extend the KBAPIRequest class. Every child must overload at least -(NSString )URL* method so that HTTP request could be performed. Of course you may add some arbitrary request properties resulting in different URL string. For example, Wikipedia API search request class may be implemented like this:

#import "WikiHeader.h"

@interface WikipediaSearchRequest: KBAPIRequest

@property (nonatomic, retain) NSString *searchText;
@property (nonatomic, assign) NSUInteger count;

@end

@implementation WikipediaSearchRequest

- (void) dealloc {
    [_searchText release];

    [super dealloc];
}

- (NSString *) URL {
    return [NSString stringWithFormat:@"http://en.wikipedia.org/w/api.php?action=opensearch&search=%@&limit=%d", self.searchText, self.count];
}

+ (Class) expected {
    return [WikiHeader class];
}

@end

Another handy method is shown here, +(Class)expected method, may be used to auto-construct response objects from JSON/XML. If receiver returns some class conforming to protocol descripbed below than every API connection with this request type would attempt to create object of this class. The protocol is:

  • KBEntity. This protocol has only one or two required methods: +(instancetype)entityFromJSON:(id)JSON and +(instancetype)entityFromXML:(GDataXMLElement )XML*. Of course if you set KBAPISUPPORT_JSON to zero or KBAPISUPPORT_XML to zero then first and second methods would disappear, respectively. If a class implements corresponding method for creating it from JSON or XML then it could be autoconstructed in response to some request.

  • KBAPIConnection. This is the most important class in the library. To use it you must first create KBAPIRequest, then you should create KBAPIConnection with this request and set the delegate to receive API events such as errors, JSON, XML or autoconstructed objects receiving. Here is an example of reading flagconfig response from Wikipedia API:

///////////////// WikipediaFlagconfigInfo /////////////////

@interface WikipediaFlagconfigInfo: NSObject <KBEntity>

@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) NSUInteger levels;
@property (nonatomic, assign) NSUInteger tier1;
@property (nonatomic, assign) NSUInteger tier2;
@property (nonatomic, assign) NSUInteger tier3;

@end

@implementation WikipediaFlagconfigInfo

- (void) dealloc {
    [_name release];

    [super dealloc];
}

+ (WikipediaFlagconfigInfo) entityFromJSON: (id) JSON {
    if (![JSON isKindOfClass:[NSArray class]] || ([JSON count] == 0) || ![[JSON objectAtIndex:0] isKindOfClass:[NSDictionary class]]) {
        return nil;
    }

    NSDictionary *flagInfoDict = [JSON objectAtIndex:0];
    WikipediaFlagconfigInfo *result = [[[self alloc] init] autorelease];

    result.name = [flagInfoDict objectForKey:@"name"];
    result.levels = [[flagInfoDict objectForKey:@"levels"] unsignedIntegerValue];
    result.tier1 = [[flagInfoDict objectForKey:@"tier1"] unsignedIntegerValue];
    result.tier2 = [[flagInfoDict objectForKey:@"tier2"] unsignedIntegerValue];
    result.tier3 = [[flagInfoDict objectForKey:@"tier3"] unsignedIntegerValue];

    return result;  
}

@end

///////////////// WikipediaFlagconfigRequest /////////////////

@interface WikipediaFlagconfigRequest: KBAPIRequest

@end

@implementation WikipediaFlagconfigRequest

- (NSString *) URL {
    return @"http://en.wikipedia.org/w/api.php?action=flagconfig&format=json";
}

+ (Class) expected {
    return [WikipediaFlagconfigInfo class];
}

@end

///////////////// some view controller or something else /////////////////

- (IBAction) buttonTapped: (id) sender {
    WikipediaFlagconfigRequest *req = [WikipediaFlagconfigRequest request];
    [[KBAPIConnection connectionWithRequest:req delegate:self] start];
}

- (void) connection: (KBAPIConnection *) connection didFailWithError:(NSError *)error {
    NSLog (@"Sorry, an error occured: %@", error);
}

- (void) connection:(KBAPIConnection *)connection didReceiveResponse: (id <KBEntity>) response {
    WikipediaFlagconfigInfo *flagInfo = response;
    NSLog (@"Fields:");
    NSLog (@"Name: %@", flagInfo.name);
    NSLog (@"Levels: %d", flagInfo.levels);
    NSLog (@"Tier1: %d", flagInfo.tier1);
    NSLog (@"Tier2: %d", flagInfo.tier2);
    NSLog (@"Tier3: %d", flagInfo.tier3);
}
  • KBEntityList. API answers include arrays of similar elements very often, so there is some generic list container. Subclasses should overload method +(Class)entityClass to enable list autoconstructing (this method must return Class of list’s elements). If you use XML you should also overload +(NSString )entityTag;* method to specify tag name of the list’s children.

  • KBAutoEntity. You may inherit your object from KBAutoEntity to use AutoObjects feature. Detailed description would be added later.

Extended Usage

For more usage examples please refer to KBAPISupport Demo projects at https://github.com/byss/KBAPISupport-Demo.

Documentation

Documentation could be generated using AppleDoc (https://github.com/tomaz/appledoc). You may use following command:

appledoc 
    --project-name 'KBAPISupport' 
    --project-company 'Kirill byss Bystrov' 
    --company-id 'ru.byss' 
    --keep-undocumented-objects 
    --keep-undocumented-members 
    --search-undocumented-doc 
    --no-repeat-first-par 
    --no-merge-categories 
    --output ~/KBAPISupport-appledoc 
    --ignore .m 
    .

Latest podspec

{
    "name": "KBAPISupport",
    "version": "4.0.0-b01",
    "license": {
        "type": "MIT"
    },
    "homepage": "https://github.com/byss/KBAPISupport",
    "authors": {
        "Kirill byss Bystrov": "[email protected]"
    },
    "summary": "Simple library for HTTP/HTTPS requests and parsing & mapping JSON/XML responses to native objects.",
    "source": {
        "git": "https://github.com/byss/KBAPISupport.git",
        "tag": "v4.0.0-b01"
    },
    "requires_arc": false,
    "frameworks": "Foundation",
    "swift_version": "4.2",
    "platforms": {
        "ios": "10.0",
        "tvos": "10.0",
        "osx": "10.12",
        "watchos": "4.0"
    },
    "module_map": "KBAPISupport/Supporting Files/KBAPISupport.modulemap",
    "pod_target_xcconfig": {
        "COPY_HEADERS_RUN_UNIFDEF": "YES",
        "COPY_HEADERS_UNIFDEF_FLAGS": "-U__cplusplus",
        "CLANG_CXX_LANGUAGE_STANDARD": "gnu++17"
    },
    "default_subspecs": "Core",
    "subspecs": [
        {
            "name": "Core",
            "source_files": [
                "KBAPISupport/Core/{Public,Internal,Private}/*.{h,m,mm,swift}",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "public_header_files": [
                "KBAPISupport/Core/Public/*.h",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "private_header_files": "KBAPISupport/Core/Internal/*.h"
        },
        {
            "name": "ObjC",
            "source_files": [
                "KBAPISupport/ObjC/{Public,Internal,Private}/*.{h,m,mm,swift}",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "public_header_files": [
                "KBAPISupport/ObjC/Public/*.h",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "dependencies": {
                "KBAPISupport/Core": []
            }
        },
        {
            "name": "ImageLoading",
            "source_files": [
                "KBAPISupport/ImageLoading/{Public,Internal,Private}/*.{h,m,mm,swift}",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "public_header_files": [
                "KBAPISupport/ImageLoading/Public/*.h",
                "KBAPISupport/Supporting Files/KBAPISupport.h"
            ],
            "dependencies": {
                "KBAPISupport/Core": []
            },
            "ios": {
                "frameworks": "UIKit"
            },
            "tvos": {
                "frameworks": "UIKit"
            },
            "osx": {
                "frameworks": "AppKit"
            }
        }
    ]
}

Pin It on Pinterest

Share This