2014-05-22 6 views
2

Мне любопытно 2 вещи:IOS - связь между объектом API и контроллерами

Что эффективный и простой в масштабе способ проектирования связи между объектом, который обменивается данными с API и viewcontrollers

как спроектировать сам сообщающийся объект (как методы проектирования быть масштабируемой, ..)

(Мой подход уже ниже грязен, я знаю, но сроки были сумасшедшими и я до сих пор не было времени подумать об этом на самом деле)

Позвольте мне представить задачу я имел дело с:.

я должен был написать 2-3 и приложения в зависимости от связи с API. Было около 10-15 различных методов, на которые API ответил (отправить через http POST, привести к JSON). Конечно, общение должно было быть асинхронным.

Мой подход:

Таким образом, объект communicationg с API (apiComm для краткости) разделялась всеми UIViewControllers. apiComm имел 10-15 методов, каждый из которых был способен обрабатывать API; существует большая вариабельность между отдельным содержанием запроса .. =>вопроса 2

Когда apiComm получили данные из API, он отправил уведомление на [NSNotificationCenter defaultCenter]. Это означает, что каждый UIViewController, который хотел использовать , apiComm должен был зарегистрировать себя для уведомлений и реализовать метод обработки входящего уведомления. Этот метод вырос противным, как некоторые UIViewController пришлись обрабатывать больше запросов API, ... =>вопроса 1

Я хотел бы знать, если есть универсальный шаблон для использования при desining этих проблем .. будет для любых комментариев по любой части этой проблемы.

+0

Отметьте это сообщение в блоге для создания хорошей структуры для обработки веб-сервисов. Я использовал его в нескольких крупных проектах сейчас, и это было ** очень хорошо: http://commandshift.co.uk/blog/2014/01/02/nice-web-services/ – liamnichols

+0

Относительно " как уведомить "- это действительно очень общее решение для программирования iOS - есть много способов! Часто KVO отлично работает; часто центр уведомлений. Скорее всего, это государственная машина; ваше приложение уже будет иметь «state» singleton. Просто позвоните ему [STATE newFeedDataIsReady], один звонок. а затем IN STATE, вы можете решить, что с этим делать, на основе приложения.если вы не пробовали KVO, экспериментируйте с ним. – Fattie

+0

Да. Спасибо, @liamnichols - очень хорошее сообщение в блоге и проект. – pothf

ответ

1

Для меня только реальные ответы или направление я могу дать этой сложной проблемы:

  • всеми средствами использовать какой-то абстрактный класс -like узор, как @liamnichols указывает

  • если вы читаете эту новость для iOS, абсолютно необходимо использовать шаблон «после ...» (примеры в коде ниже)

  • В этом пункте, здесь есть абсолютно критический момент в iOS/объективе-C https://stackoverflow.com/a/20760583/294884 .. как сделать блок собственности

  • чисто ИМО, я никогда не нашел большой проект, где «15 предметов» действительно могут быть действительно рационализированы. этого еще не произошло. так что лучшее для нас это тщательно - по крайней мере - упакуйте его так, чтобы (так или иначе) вы называете «15 предметов» что-то вроде этого .. CLOUD.NOTES .. CLOUD.PROFILE .. CLOUD.SCORES .. и так далее от остальной части вашего кода.

  • использование одноэлементно (s), конечно, для систем сетевого

  • очень важно получить как с КВО и NSNotifications для сетевых систем

  • это очень важно отметить, что это так нелепо легко для обработки JSON в юниверсе iOS, в наши дни, что (к счастью), имеющее «всего 15 отдельных файлов» {так или иначе), действительно не так уж плохо, и было бы легко увидеть, что это действительно, о самом окончательном рационализации, которую вы можете сделать.

Итак, только некоторые смешанные мысли. Один последний момент - все просто движется к parse.com так все это становится спорным, к счастью :)

Это почти случай «Я работаю с клиентом, который hans't еще переехал в Баас (» нет, действительно! »), так как я могу сохранить код сети аккуратно ...» Хех.


Не может быть проще, просто написать хороший одноплодной.

Оставьте заявку в любом приложении, которое в ней нуждается.

Это невероятно легко обрабатывается JSON в iOS в эти дни. Итак, то, что я описываю, часто тривиально. Немного больше, чем несколько десятков строк кода.

Ваши «облачные» файлы будут содержать подпрограммы этого простого ... этот одноэлемент будет называться «BLANKS» или аналогичным ... он получает некоторые «пустые» типы файлов пользователя с сервера, скажем так.

-(void)loadIfNeededThen:(void(^)(void))after 
    { 
    if (self.rawStubsFromCloud != nil) 
     { 
     NSLog(@"good new, blanks are already loaded!!"); 
     after(); 
     return; 
     } 

    [APP huddie]; // (use MBProgressHUD for all spinners) 
    APP.hud.labelText = @"Loading file blanks from cloud..."; 

    dispatch_after_secs_on_main(0.1 , 
      ^{ 
      [self _refreshThen: 
       ^{ 
       [APP.hud hide:YES]; 

       NSLog(@"loaded the blanks fine:\n%@\n", 
        [self supplyDisplayStyleString]); 

       after(); 
       }]; 
      } 
     ); 
    } 
-(void)_refresh 
    { 
    [self _refreshThen:nil]; 
    } 

#define uBlanks [NSURL URLWithString:@"http://blah.com/json/blanks"] 
-(void)_refreshThen:(void(^)(void))after 
    { 
    dispatch_async(dispatch_get_main_queue(), 
     ^{ 
     self.rawBlanksFromCloud = [NSData dataWithContentsOfURL:uBlanks]; 

     [self _doShowAllOnLog]; 

     after(); 
     }); 
    } 

Это стоит понимать, что все движется к Parse.com и других Баас. Другого реалистического будущего нет, с конца этого года не будет «серверной стороны».

Так что на практике эти простые синглеты становятся еще проще - это всего лишь несколько строк кода, которые можно подключить к Parse. Наслаждайтесь!

Таким образом, TBC приведенный выше пример кода относится к ситуации «ye olde web server».

Вот пример получения «пользовательские файлы» .. (обратите внимание на удобную рутинную postStringUser для сборки проклятый URL называет .. Я никогда не нашел действительно аккуратный способ сделать это!) ...

-(NSString *)postStringUser:(NSString *)user pass:(NSString *)pass 
{ 
NSString *username = user; 
NSString *password = pass; 

NSMutableString *r = [NSMutableString stringWithString:@""]; 

[r appendString:@"command=commandExampleGetFile"]; 
[r appendString:@"&"]; 

[r appendString:@"name=blah"]; 
[r appendString:@"&"]; 

[r appendString:@"user="]; 
[r appendString: [username stringByUrlEncoding] ]; 
[r appendString:@"&"]; 

[r appendString:@"password="]; 
[r appendString: [password stringByUrlEncoding] ]; 

return r; 
} 

#define yourUrl [NSURL URLWithString:@"http://blah.com/json/blah"] 

-(void)fetchTheUsersFiles:(NSString *)user pass:(NSString *)pass then:(void(^)(void))after 
{ 
NSString *postString = [self postStringUser:user pass:pass]; 
NSLog(@"postString is %@ ", postString); 

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:yourUrl]; 
request.HTTPMethod = @"POST"; 
request.HTTPBody = [ postString dataUsingEncoding:NSUTF8StringEncoding]; 
[request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField: @"Content-Type"]; 

[APP huddie]; // use MBProgress everywhere and always at all times in all apps always 
APP.hud.labelText = @"Connecting to the cloud..."; 

// 1 get the data 
// 2 make it a jdic 
// 3 make it an array of the "files" 

[NSURLConnection 
    sendAsynchronousRequest: request 
    queue: [NSOperationQueue mainQueue] 
    completionHandler:^(NSURLResponse *r, NSData *data, NSError *error) 
    { 
    [APP.hud hide:YES]; 
    NSLog(@"Done... %@", r); 

    self.rawGetFilesFromCloud = data; 

    NSError* err; 
    NSDictionary* jdic = [NSJSONSerialization 
     JSONObjectWithData:self.rawGetFilesFromCloud 
     options:kNilOptions 
     error:&err]; 

     //dev only 
     NSLog(@"Here's the whole damned jdic, for GetFiles\n%@", jdic); 

    if (! jdic) 
     { 
     [APP simpleOK:@"Wrong username or pass? Or no files found."]; 
     } 
    else 
     { 
     // the user has "logged in" so something like 
     STATE.currentUsername = user; 
     STATE.currentPassword = pass; 
     // naturally you have a STATE singleton, every app needs one 

     self.rawArrayFromCloud = [jdic objectForKey:@"data"]; 

     NSInteger kUserFiles = self.rawArrayFromCloud.count; 
     NSString *sayString = [NSString stringWithFormat: 
     @"We found %lu files of yours on the damned cloud.", kUserFiles]; 

     /* 
     and for example... 
     STATE.fileZero = self.rawArrayFromCloud[0]; 
     or for example... 
     NSDictionary *oneStubDict = self.rawArrayFromCloud[17]; 
     NSString *subjectName = oneStubDict[@"subjectName"]; 
     NSString *mainBody = oneStubDict[@"mainBody"]; 
     NSString *authorField = oneStubDict[@"authorField"]; 
     */ 

     [APP simpleOK: sayString 
      then:^{ [STATE showFileInterface]; } ]; 
     } 

    if (after) after(); 
    }]; 

} 

Примечания критического код немного больше, чем ...

NSMutableURLRequest *request = ... 

[NSURLConnection sendAsynchronousRequest: request ... 

NSDictionary* jdic = [NSJSONSerialization JSONObjectWithData:result ... 

NSArray *theFiles = [jdic objectForKey:@"theFiles"]; 

NSString *aField = theFiles[13]["coverInfo"]["aField"]; 

Надеется, что это помогает!

+0

Спасибо, @JoeBlow, за ваш ответ. Я не уверен, правильно ли я это понимаю. Мой «общий объект apiComm» был синглом. Моя проблема не заключалась в создании запроса POST, но для эффективного создания набора различных запросов. В конце разработки приложения было более 10 методов, таких как ваш _- (NSString *) postStringUser: (NSString *) пользовательский пароль: (NSString *) pass_ (пользователь CRUD и CRUD его события и т. Д.), И я могу " Представьте, что вы делаете это с помощью большего приложения. Но спасибо, мне нравится создание BLANKS. – pothf

+0

Хмм, я не совсем уверен, что вы спрашиваете - если вы взглянете на метод postStringUser: «........ вы говорите:« Вам надоело иметь 15 из тех, кто имеет дело с «.. что такое ситуация? – Fattie

+0

Я хотел бы остановиться, но у меня пока нет достаточной репутации. И да, это ситуация. Мне было интересно, есть ли какой-то шаблон, который можно использовать при создании приложения с действительно богатой связью с API. – pothf

Смежные вопросы