OSDN Git Service

Coredataにデータを保存してみるテスト
authormasakih <masakih@users.sourceforge.jp>
Fri, 14 Feb 2014 16:14:22 +0000 (01:14 +0900)
committermasakih <masakih@users.sourceforge.jp>
Fri, 14 Feb 2014 16:14:22 +0000 (01:14 +0900)
KCD.xcodeproj/project.pbxproj
KCD/HMAppDelegate.h
KCD/HMAppDelegate.m
KCD/HMCompositCommand.h [new file with mode: 0644]
KCD/HMCompositCommand.m [new file with mode: 0644]
KCD/HMJSONCommand.h
KCD/HMJSONCommand.m
KCD/HMJSONViewCommand.m
KCD/HMMasterSTypeCommand.h [new file with mode: 0644]
KCD/HMMasterSTypeCommand.m [new file with mode: 0644]
KCD/KCD.xcdatamodeld/KCD.xcdatamodel/contents [new file with mode: 0644]

index b69672a..16962a1 100644 (file)
@@ -11,6 +11,7 @@
                F46F104118A9B85E0063E503 /* HMJSONNode.m in Sources */ = {isa = PBXBuildFile; fileRef = F46F104018A9B85E0063E503 /* HMJSONNode.m */; };
                F46F104518AA50730063E503 /* HMBroserWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F46F104318AA50730063E503 /* HMBroserWindowController.m */; };
                F46F104618AA50730063E503 /* HMBroserWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F46F104418AA50730063E503 /* HMBroserWindowController.xib */; };
+               F46F104918ABAC910063E503 /* KCD.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F46F104718ABAC910063E503 /* KCD.xcdatamodeld */; };
                F47B78B218A7B42B0011386E /* HMJSONViewWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = F47B78B018A7B42B0011386E /* HMJSONViewWindowController.m */; };
                F47B78B318A7B42B0011386E /* HMJSONViewWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F47B78B118A7B42B0011386E /* HMJSONViewWindowController.xib */; };
                F4BDEB47187252F30069D0CE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4BDEB46187252F30069D0CE /* Cocoa.framework */; };
@@ -33,6 +34,8 @@
                F4C1190518A71AEA005D5B25 /* HMJSONReciever.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C1190418A71AEA005D5B25 /* HMJSONReciever.m */; };
                F4C1190818A746EB005D5B25 /* HMJSONTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C1190718A746EB005D5B25 /* HMJSONTracker.m */; };
                F4C1190B18A74DF0005D5B25 /* HMJSONCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C1190A18A74DF0005D5B25 /* HMJSONCommand.m */; };
+               F4D2CBC218AD0E1A000EBC59 /* HMMasterSTypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D2CBC118AD0E1A000EBC59 /* HMMasterSTypeCommand.m */; };
+               F4D2CBC518AE2AE2000EBC59 /* HMCompositCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D2CBC418AE2AE2000EBC59 /* HMCompositCommand.m */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -53,6 +56,7 @@
                F46F104218AA50730063E503 /* HMBroserWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMBroserWindowController.h; sourceTree = "<group>"; };
                F46F104318AA50730063E503 /* HMBroserWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMBroserWindowController.m; sourceTree = "<group>"; };
                F46F104418AA50730063E503 /* HMBroserWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HMBroserWindowController.xib; sourceTree = "<group>"; };
+               F46F104818ABAC910063E503 /* KCD.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = KCD.xcdatamodel; sourceTree = "<group>"; };
                F47B78AF18A7B42B0011386E /* HMJSONViewWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMJSONViewWindowController.h; sourceTree = "<group>"; };
                F47B78B018A7B42B0011386E /* HMJSONViewWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMJSONViewWindowController.m; sourceTree = "<group>"; };
                F47B78B118A7B42B0011386E /* HMJSONViewWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HMJSONViewWindowController.xib; sourceTree = "<group>"; };
                F4C1190718A746EB005D5B25 /* HMJSONTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMJSONTracker.m; sourceTree = "<group>"; };
                F4C1190918A74DF0005D5B25 /* HMJSONCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMJSONCommand.h; sourceTree = "<group>"; };
                F4C1190A18A74DF0005D5B25 /* HMJSONCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMJSONCommand.m; sourceTree = "<group>"; };
+               F4D2CBC018AD0E1A000EBC59 /* HMMasterSTypeCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMMasterSTypeCommand.h; sourceTree = "<group>"; };
+               F4D2CBC118AD0E1A000EBC59 /* HMMasterSTypeCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMMasterSTypeCommand.m; sourceTree = "<group>"; };
+               F4D2CBC318AE2AE2000EBC59 /* HMCompositCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMCompositCommand.h; sourceTree = "<group>"; };
+               F4D2CBC418AE2AE2000EBC59 /* HMCompositCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMCompositCommand.m; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                F4BDEB4C187252F30069D0CE /* KCD */ = {
                        isa = PBXGroup;
                        children = (
-                               F4C118F318A67B05005D5B25 /* New Group */,
+                               F4C118F318A67B05005D5B25 /* CustomHTTPProtocol */,
                                F4BDEB58187252F30069D0CE /* HMAppDelegate.h */,
                                F4BDEB59187252F30069D0CE /* HMAppDelegate.m */,
                                F4C1190318A71AEA005D5B25 /* HMJSONReciever.h */,
                                F4C1190418A71AEA005D5B25 /* HMJSONReciever.m */,
                                F4C1190618A746EB005D5B25 /* HMJSONTracker.h */,
                                F4C1190718A746EB005D5B25 /* HMJSONTracker.m */,
-                               F4C1190918A74DF0005D5B25 /* HMJSONCommand.h */,
-                               F4C1190A18A74DF0005D5B25 /* HMJSONCommand.m */,
-                               F46F103418A7CE310063E503 /* HMJSONViewCommand.h */,
-                               F46F103518A7CE310063E503 /* HMJSONViewCommand.m */,
+                               F4D2CBBF18ACE7D7000EBC59 /* Command */,
                                F46F103F18A9B85E0063E503 /* HMJSONNode.h */,
                                F46F104018A9B85E0063E503 /* HMJSONNode.m */,
                                F4C1190018A6FFC2005D5B25 /* HMQueue.h */,
                                F47B78AF18A7B42B0011386E /* HMJSONViewWindowController.h */,
                                F47B78B018A7B42B0011386E /* HMJSONViewWindowController.m */,
                                F47B78B118A7B42B0011386E /* HMJSONViewWindowController.xib */,
+                               F46F104718ABAC910063E503 /* KCD.xcdatamodeld */,
                        );
                        path = KCD;
                        sourceTree = "<group>";
                        name = "Supporting Files";
                        sourceTree = "<group>";
                };
-               F4C118F318A67B05005D5B25 /* New Group */ = {
+               F4C118F318A67B05005D5B25 /* CustomHTTPProtocol */ = {
                        isa = PBXGroup;
                        children = (
                                F4C118F418A67B1C005D5B25 /* CacheStoragePolicy.h */,
                                F4C118F818A67B1C005D5B25 /* CustomHTTPProtocol.h */,
                                F4C118F918A67B1C005D5B25 /* CustomHTTPProtocol.m */,
                        );
-                       name = "New Group";
+                       name = CustomHTTPProtocol;
+                       sourceTree = "<group>";
+               };
+               F4D2CBBF18ACE7D7000EBC59 /* Command */ = {
+                       isa = PBXGroup;
+                       children = (
+                               F4C1190918A74DF0005D5B25 /* HMJSONCommand.h */,
+                               F4C1190A18A74DF0005D5B25 /* HMJSONCommand.m */,
+                               F4D2CBC318AE2AE2000EBC59 /* HMCompositCommand.h */,
+                               F4D2CBC418AE2AE2000EBC59 /* HMCompositCommand.m */,
+                               F46F103418A7CE310063E503 /* HMJSONViewCommand.h */,
+                               F46F103518A7CE310063E503 /* HMJSONViewCommand.m */,
+                               F4D2CBC018AD0E1A000EBC59 /* HMMasterSTypeCommand.h */,
+                               F4D2CBC118AD0E1A000EBC59 /* HMMasterSTypeCommand.m */,
+                       );
+                       name = Command;
                        sourceTree = "<group>";
                };
 /* End PBXGroup section */
                        isa = PBXSourcesBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               F4D2CBC518AE2AE2000EBC59 /* HMCompositCommand.m in Sources */,
                                F4C1190218A6FFC2005D5B25 /* HMQueue.m in Sources */,
                                F46F103618A7CE310063E503 /* HMJSONViewCommand.m in Sources */,
                                F4C118FA18A67B1C005D5B25 /* CacheStoragePolicy.m in Sources */,
                                F4C1190818A746EB005D5B25 /* HMJSONTracker.m in Sources */,
                                F4C118FB18A67B1C005D5B25 /* CanonicalRequest.m in Sources */,
                                F4BDEB5A187252F30069D0CE /* HMAppDelegate.m in Sources */,
+                               F46F104918ABAC910063E503 /* KCD.xcdatamodeld in Sources */,
+                               F4D2CBC218AD0E1A000EBC59 /* HMMasterSTypeCommand.m in Sources */,
                                F46F104518AA50730063E503 /* HMBroserWindowController.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                        defaultConfigurationName = Release;
                };
 /* End XCConfigurationList section */
+
+/* Begin XCVersionGroup section */
+               F46F104718ABAC910063E503 /* KCD.xcdatamodeld */ = {
+                       isa = XCVersionGroup;
+                       children = (
+                               F46F104818ABAC910063E503 /* KCD.xcdatamodel */,
+                       );
+                       currentVersion = F46F104818ABAC910063E503 /* KCD.xcdatamodel */;
+                       path = KCD.xcdatamodeld;
+                       sourceTree = "<group>";
+                       versionGroupType = wrapper.xcdatamodel;
+               };
+/* End XCVersionGroup section */
        };
        rootObject = F4BDEB3B187252F30069D0CE /* Project object */;
 }
index 7a5d80a..c4a78d0 100644 (file)
 
 @interface HMAppDelegate : NSObject <NSApplicationDelegate>
 
+@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
+@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
+@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
+
+
 - (void)logLineReturn:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
 - (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
 
index d2e9c0e..8498484 100644 (file)
 
 @implementation HMAppDelegate
 
+@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
+@synthesize managedObjectModel = _managedObjectModel;
+@synthesize managedObjectContext = _managedObjectContext;
+
+
 static FILE* logFileP = NULL;
 
 + (void)initialize
@@ -116,4 +121,172 @@ static FILE* logFileP = NULL;
        }];
 }
 
+
+
+
+// Returns the directory the application uses to store the Core Data store file. This code uses a directory named "com.masakih.KanColleLevelManager" in the user's Application Support directory.
+- (NSURL *)applicationFilesDirectory
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
+    return [appSupportURL URLByAppendingPathComponent:@"com.masakih.KCD"];
+}
+
+// Creates if necessary and returns the managed object model for the application.
+- (NSManagedObjectModel *)managedObjectModel
+{
+    if (_managedObjectModel) {
+        return _managedObjectModel;
+    }
+       
+    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"KCD" withExtension:@"momd"];
+    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
+    return _managedObjectModel;
+}
+
+// Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)
+- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
+{
+    if (_persistentStoreCoordinator) {
+        return _persistentStoreCoordinator;
+    }
+    
+    NSManagedObjectModel *mom = [self managedObjectModel];
+    if (!mom) {
+        NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));
+        return nil;
+    }
+    
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSURL *applicationFilesDirectory = [self applicationFilesDirectory];
+    NSError *error = nil;
+    
+    NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:@[NSURLIsDirectoryKey] error:&error];
+    
+    if (!properties) {
+        BOOL ok = NO;
+        if ([error code] == NSFileReadNoSuchFileError) {
+            ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error];
+        }
+        if (!ok) {
+            [[NSApplication sharedApplication] presentError:error];
+            return nil;
+        }
+    } else {
+        if (![properties[NSURLIsDirectoryKey] boolValue]) {
+            // Customize and localize this error.
+            NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]];
+            
+            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+            [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
+            error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
+            
+            [[NSApplication sharedApplication] presentError:error];
+            return nil;
+        }
+    }
+    
+    NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"KCD.storedata"];
+       NSDictionary *options = @{
+                                                         NSMigratePersistentStoresAutomaticallyOption : @YES,
+                                                         NSInferMappingModelAutomaticallyOption : @YES
+                                                         };
+    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
+    if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:options error:&error]) {
+        [[NSApplication sharedApplication] presentError:error];
+        return nil;
+    }
+    _persistentStoreCoordinator = coordinator;
+    
+    return _persistentStoreCoordinator;
+}
+
+// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
+- (NSManagedObjectContext *)managedObjectContext
+{
+    if (_managedObjectContext) {
+        return _managedObjectContext;
+    }
+    
+    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
+    if (!coordinator) {
+        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
+        [dict setValue:@"Failed to initialize the store" forKey:NSLocalizedDescriptionKey];
+        [dict setValue:@"There was an error building up the data file." forKey:NSLocalizedFailureReasonErrorKey];
+        NSError *error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
+        [[NSApplication sharedApplication] presentError:error];
+        return nil;
+    }
+    _managedObjectContext = [[NSManagedObjectContext alloc] init];
+    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
+       
+    return _managedObjectContext;
+}
+
+// Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
+- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
+{
+    return [[self managedObjectContext] undoManager];
+}
+
+// Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.
+- (IBAction)saveAction:(id)sender
+{
+    NSError *error = nil;
+    
+    if (![[self managedObjectContext] commitEditing]) {
+        NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd));
+    }
+    
+    if (![[self managedObjectContext] save:&error]) {
+        [[NSApplication sharedApplication] presentError:error];
+    }
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+    // Save changes in the application's managed object context before the application terminates.
+    
+    if (!_managedObjectContext) {
+        return NSTerminateNow;
+    }
+    
+    if (![[self managedObjectContext] commitEditing]) {
+        NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));
+        return NSTerminateCancel;
+    }
+    
+    if (![[self managedObjectContext] hasChanges]) {
+        return NSTerminateNow;
+    }
+    
+    NSError *error = nil;
+    if (![[self managedObjectContext] save:&error]) {
+               
+        // Customize this code block to include application-specific recovery steps.
+        BOOL result = [sender presentError:error];
+        if (result) {
+            return NSTerminateCancel;
+        }
+               
+        NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");
+        NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
+        NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
+        NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
+        NSAlert *alert = [[NSAlert alloc] init];
+        [alert setMessageText:question];
+        [alert setInformativeText:info];
+        [alert addButtonWithTitle:quitButton];
+        [alert addButtonWithTitle:cancelButton];
+               
+        NSInteger answer = [alert runModal];
+        
+        if (answer == NSAlertAlternateReturn) {
+            return NSTerminateCancel;
+        }
+    }
+       
+    return NSTerminateNow;
+}
+
 @end
diff --git a/KCD/HMCompositCommand.h b/KCD/HMCompositCommand.h
new file mode 100644 (file)
index 0000000..5a4b80c
--- /dev/null
@@ -0,0 +1,17 @@
+//
+//  HMCompositCommand.h
+//  KCD
+//
+//  Created by Hori,Masaki on 2014/02/14.
+//  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
+//
+
+#import "HMJSONCommand.h"
+
+#ifdef DEBUG
+@interface HMCompositCommand : HMJSONCommand
+
++ (id)compositCommandWithCommands:(HMJSONCommand *)cmd1, ...;
+
+@end
+#endif
\ No newline at end of file
diff --git a/KCD/HMCompositCommand.m b/KCD/HMCompositCommand.m
new file mode 100644 (file)
index 0000000..4bd078e
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  HMCompositCommand.m
+//  KCD
+//
+//  Created by Hori,Masaki on 2014/02/14.
+//  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
+//
+
+#import "HMCompositCommand.h"
+
+#ifdef DEBUG
+
+@interface HMCompositCommand ()
+@property (retain) NSMutableArray *commands;
+@end
+
+
+@implementation HMCompositCommand
+
++ (id)compositCommandWithCommands:(HMJSONCommand *)cmd1, ...
+{
+       HMCompositCommand *result = [HMCompositCommand new];
+       
+       result.commands = [NSMutableArray new];
+       
+       va_list ap;
+       va_start(ap, cmd1);
+       HMJSONCommand *command = cmd1;
+       while(command) {
+               [result.commands addObject:command];
+               command = va_arg(ap, id);
+       }
+       va_end(ap);
+       
+       return result;
+}
+
+- (void)execute
+{
+       for(HMJSONCommand *command in self.commands) {
+               [command execute];
+       }
+}
+- (void)prepaierOnMainThread
+{
+       for(id command in self.commands) {
+               [command prepaierOnMainThread];
+       }
+}
+
+- (void)setArgumentsString:(NSString *)argumentsString
+{
+       for(id command in self.commands) {
+               [command setArgumentsString:argumentsString];
+       }
+}
+- (void)setJsonData:(NSData *)jsonData
+{
+       for(id command in self.commands) {
+               [command setJsonData:jsonData];
+       }
+}
+
+
+@end
+
+#endif
index e1a488e..803800b 100644 (file)
 
 
 // for subclass
-@property (copy, readonly) NSString *api;
++ (void)registerClass:(Class)commandClass;
+
+@property (copy, readonly) NSString *api;      // api is /kcsapi/mainAPI/subAPI
+NSString *mainAPI(NSString *api);
+NSString *subAPI(NSString *api);
 @property (retain, readonly) NSArray *arguments;
 @property (retain, readonly) id json;          // NSArray or NSDictionary
 @property (retain, readonly) NSArray *jsonTree;        // for NSTreeController
 
-
 + (BOOL)canExcuteAPI:(NSString *)api;
-+ (void)registerClass:(Class)commandClass;
 
 // メインスレッド上での準備が必要な場合は実装する
 - (void)prepaierOnMainThread;
 
+
+NSString *keyByDeletingPrefix(NSString *key);
+
+- (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
+
 @end
index 2a0ab99..b8693af 100644 (file)
 #import "HMAppDelegate.h"
 #import "HMJSONNode.h"
 
-static NSMutableArray *registerdCommands = nil;
+#ifdef DEBUG
+#import "HMCompositCommand.h"
+#import "HMJSONViewCommand.h"
+#endif
+
+static NSMutableArray *registeredCommands = nil;
 
 
 @interface HMJSONCommand ()
@@ -20,6 +25,8 @@ static NSMutableArray *registerdCommands = nil;
 @property (retain, readwrite) id json;
 @property (retain, readwrite) NSArray *jsonTree;
 
+
+
 @end
 
 @implementation HMJSONCommand
@@ -30,20 +37,29 @@ static NSMutableArray *registerdCommands = nil;
 {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
-               registerdCommands = [NSMutableArray new];
+               registeredCommands = [NSMutableArray new];
        });
 }
 
 + (HMJSONCommand *)commandForAPI:(NSString *)api
 {
-       for(Class commandClass in registerdCommands) {
+       for(Class commandClass in registeredCommands) {
                if([commandClass canExcuteAPI:api]) {
                        HMJSONCommand *command =  [commandClass new];
                        command.api = api;
-                       
+#ifdef DEBUG
+                       HMJSONViewCommand *viewCommand = [HMJSONViewCommand new];
+                       viewCommand.api = api;
+                       command = [HMCompositCommand compositCommandWithCommands:viewCommand, command, nil];
+#endif
                        return command;
                }
        }
+#ifdef DEBUG
+       HMJSONViewCommand *viewCommand = [HMJSONViewCommand new];
+       viewCommand.api = api;
+       return viewCommand;
+#endif
        
        return nil;
 }
@@ -51,8 +67,8 @@ static NSMutableArray *registerdCommands = nil;
 + (void)registerClass:(Class)commandClass
 {
        if(!commandClass) return;
-       if([registerdCommands containsObject:commandClass]) return;
-       [registerdCommands addObject:commandClass];
+       if([registeredCommands containsObject:commandClass]) return;
+       [registeredCommands addObject:commandClass];
 }
 
 
@@ -86,16 +102,47 @@ static NSMutableArray *registerdCommands = nil;
                                                                                                error:&error];
        if(error) {
                [[NSApp delegate] logLineReturn:@"\e[1m\e[31mFail decode JSON data\e[39m\e[22m %@", error];
-       } else {
-               self.json = json;
-               self.jsonTree = @[[HMJSONNode nodeWithJSON:json]];
+               return;
+       }
+       if(![json isKindOfClass:[NSDictionary class]]) {
+               [self log:@"JSON is NOR NSDictionary."];
+               return;
+       }
+       if(![[json objectForKey:@"api_result"] isEqual:@1]) {
+               [self log:@"API result is fail."];
+               return;
        }
+       self.json = json;
+       self.jsonTree = @[[HMJSONNode nodeWithJSON:json]];
 }
 - (NSData *)jsonData
 {
        return _jsonData;
 }
 
+NSString *mainAPI(NSString *api)
+{
+       NSString *path = [api stringByDeletingLastPathComponent];
+       return [path lastPathComponent];
+}
+NSString *subAPI(NSString *api)
+{
+       return [api lastPathComponent];
+}
+NSString *keyByDeletingPrefix(NSString *key)
+{
+       return [key substringFromIndex:4];
+}
+- (void)log:(NSString *)format, ...
+{
+       va_list ap;
+       va_start(ap, format);
+       NSString *str = [[NSString alloc] initWithFormat:format arguments:ap];
+       NSLog(@"API: %@, Arguments: %@.\nA%@", self.api, self.arguments, str);
+       va_end(ap);
+}
+
+
 // abstruct
 - (void)execute
 {
@@ -109,4 +156,6 @@ static NSMutableArray *registerdCommands = nil;
 }
 - (void)prepaierOnMainThread {}
 
+
+
 @end
index 4088d07..42e670b 100644 (file)
 @end
 
 @implementation HMJSONViewCommand
-+ (void)load
-{
-       static dispatch_once_t onceToken;
-       dispatch_once(&onceToken, ^{
-               [HMJSONCommand registerClass:self];
-       });
-}
+//+ (void)load
+//{
+//     static dispatch_once_t onceToken;
+//     dispatch_once(&onceToken, ^{
+//             [HMJSONCommand registerClass:self];
+//     });
+//}
 
 + (BOOL)canExcuteAPI:(NSString *)api
 {
diff --git a/KCD/HMMasterSTypeCommand.h b/KCD/HMMasterSTypeCommand.h
new file mode 100644 (file)
index 0000000..1c8a990
--- /dev/null
@@ -0,0 +1,13 @@
+//
+//  HMMasterSTypeCommand.h
+//  KCD
+//
+//  Created by Hori,Masaki on 2014/02/13.
+//  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
+//
+
+#import "HMJSONCommand.h"
+
+@interface HMMasterSTypeCommand : HMJSONCommand
+
+@end
diff --git a/KCD/HMMasterSTypeCommand.m b/KCD/HMMasterSTypeCommand.m
new file mode 100644 (file)
index 0000000..3a9d33d
--- /dev/null
@@ -0,0 +1,64 @@
+//
+//  HMMasterSTypeCommand.m
+//  KCD
+//
+//  Created by Hori,Masaki on 2014/02/13.
+//  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
+//
+
+#import "HMMasterSTypeCommand.h"
+
+#import "HMAppDelegate.h"
+
+
+@implementation HMMasterSTypeCommand
++ (void)load
+{
+       static dispatch_once_t onceToken;
+       dispatch_once(&onceToken, ^{
+               [HMJSONCommand registerClass:self];
+       });
+}
+
++ (BOOL)canExcuteAPI:(NSString *)api
+{
+       return [api isEqualToString:@"/kcsapi/api_get_master/stype"];
+}
+
+- (void)execute
+{
+       NSArray *api_data = [self.json objectForKey:@"api_data"];
+       if(![api_data isKindOfClass:[NSArray class]]) {
+               [self log:@"api_data is NOT NSArray."];
+               return;
+       }
+       
+       NSManagedObjectContext *managedObjectContext = [[NSApp delegate] managedObjectContext];
+       
+       for(NSDictionary *type in api_data) {
+               NSString *stypeID = type[@"api_id"];
+               NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"MasterSType"];
+               NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", stypeID];
+               [req setPredicate:predicate];
+               NSError *error = nil;
+               id result = [managedObjectContext executeFetchRequest:req
+                                                                                       error:&error];
+               if(error) {
+                       [self log:@"Fetch error: %@", error];
+                       continue;
+               }
+               NSManagedObject *object = nil;
+               if(!result || [result count] == 0) {
+                       object = [NSEntityDescription insertNewObjectForEntityForName:@"MasterSType"
+                                                                                                  inManagedObjectContext:managedObjectContext];
+               } else {
+                       object = result[0];
+               }
+               
+               for(NSString *originalKey in type) {
+                       NSString *key = keyByDeletingPrefix(originalKey);
+                       [object setValue:type[originalKey] forKey:key];
+               }
+       }
+}
+@end
diff --git a/KCD/KCD.xcdatamodeld/KCD.xcdatamodel/contents b/KCD/KCD.xcdatamodeld/KCD.xcdatamodel/contents
new file mode 100644 (file)
index 0000000..a9e3781
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="3401" systemVersion="13B42" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
+    <entity name="MasterShip" syncable="YES">
+        <attribute name="houg0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="houg1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="kaih0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="kaih1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="luck0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="luck1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="raig0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="raig1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="saku0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="saku1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="souk0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="souk1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="taik0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="taik1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tais0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tais1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tous0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tous1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tyku0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="tyku1" attributeType="Integer 32" syncable="YES"/>
+        <relationship name="after" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MasterShipAfter" inverseName="ship" inverseEntity="MasterShipAfter" syncable="YES"/>
+        <relationship name="spec" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MasterShipSpec" inverseName="ship" inverseEntity="MasterShipSpec" syncable="YES"/>
+        <relationship name="stype" maxCount="1" deletionRule="Nullify" destinationEntity="MasterSType" inverseName="ships" inverseEntity="MasterSType" syncable="YES"/>
+    </entity>
+    <entity name="MasterShipAfter" syncable="YES">
+        <attribute name="afterbull" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="afterfuel" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="afterlv" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="aftershipid" attributeType="Integer 32" syncable="YES"/>
+        <relationship name="ship" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MasterShip" inverseName="after" inverseEntity="MasterShip" syncable="YES"/>
+    </entity>
+    <entity name="MasterShipSpec" syncable="YES">
+        <attribute name="broken0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="broken1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="broken2" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="broken3" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="buildtime" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="bull_max" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="cnum" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="ctype" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="fuel_max" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="id" attributeType="Integer 32" indexed="YES" syncable="YES"/>
+        <attribute name="leng" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="maxeq0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="maxeq1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="maxeq2" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="maxeq3" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="maxeq4" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="name" attributeType="String" indexed="YES" syncable="YES"/>
+        <attribute name="powup0" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="powup1" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="powup2" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="powup3" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="shokh" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="sinfo" attributeType="String" syncable="YES"/>
+        <attribute name="slot_num" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="sortno" attributeType="Integer 32" indexed="YES" syncable="YES"/>
+        <attribute name="yomi" attributeType="String" indexed="YES" syncable="YES"/>
+        <relationship name="ship" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MasterShip" inverseName="spec" inverseEntity="MasterShip" syncable="YES"/>
+    </entity>
+    <entity name="MasterSType" syncable="YES">
+        <attribute name="id" attributeType="Integer 32" indexed="YES" syncable="YES"/>
+        <attribute name="kcnt" optional="YES" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="name" attributeType="String" indexed="YES" syncable="YES"/>
+        <attribute name="scnt" optional="YES" attributeType="Integer 32" syncable="YES"/>
+        <attribute name="sortno" attributeType="Integer 32" indexed="YES" syncable="YES"/>
+        <relationship name="ships" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="MasterShip" inverseName="stype" inverseEntity="MasterShip" syncable="YES"/>
+    </entity>
+    <elements>
+        <element name="MasterSType" positionX="0" positionY="0" width="0" height="0"/>
+        <element name="MasterShip" positionX="0" positionY="0" width="0" height="0"/>
+        <element name="MasterShipAfter" positionX="0" positionY="0" width="0" height="0"/>
+        <element name="MasterShipSpec" positionX="0" positionY="0" width="0" height="0"/>
+    </elements>
+</model>
\ No newline at end of file