Вандад Нахавандипур - iOS. Приемы программирования
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSString *urlAsString = <# Здесь укажите URL веб-сервера #>;
urlAsString = [urlAsString stringByAppendingString:@"?param1=First"];
urlAsString = [urlAsString stringByAppendingString:@"¶m2=Second"];
NSURL *url = [NSURL URLWithString: urlAsString];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL: url];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest setHTTPMethod:@"DELETE"];
NSString *body = @"bodyParam1=BodyValue1&bodyParam2=BodyValue2";
[urlRequest setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection
sendAsynchronousRequest: urlRequest
queue: queue
completionHandler: ^(NSURLResponse *response,
NSData *data,
NSError *error) {
if ([data length] >0 &&
error == nil){
NSString *html = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
NSLog(@"HTML = %@", html);
}
else if ([data length] == 0 &&
error == nil){
NSLog(@"Nothing was downloaded.");
}
else if (error!= nil){
NSLog(@"Error happened = %@", error);
}
}];
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Этот пример очень напоминает код, рассмотренный в разделах 11.5 и 11.6. Разница заключается в том, что здесь мы использовали HTTP-метод DELETE. Прочая информация практически идентична той, что была изложена в упомянутых разделах.
11.8. Отправка запросов HTTP PUT с применением NSURLConnection
Постановка задачи
Требуется вызывать веб-службу методом HTTP PUT, чтобы размещать ресурс на веб-сервере и, возможно, передать веб-службе определенные параметры, которые будут находиться в теле HTTP или в строке запроса.
Решение
Как и методы GET, POST и DELETE, метод PUT можно использовать с помощью NSURLConnection. Необходимо явно задать метод вашего URL как PUT.
Обсуждение
Напишем простое приложение, которое будет создавать асинхронное соединение и отправлять несколько параметров в строке запроса, а несколько — в теле HTTP. Отправка будет происходить по указанному URL с помощью метода PUT:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSString *urlAsString = <# Здесь укажите URL веб-сервера #>;
urlAsString = [urlAsString stringByAppendingString:@"?param1=First"];
urlAsString = [urlAsString stringByAppendingString:@"¶m2=Second"];
NSURL *url = [NSURL URLWithString: urlAsString];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL: url];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest setHTTPMethod:@"PUT"];
NSString *body = @"bodyParam1=BodyValue1&bodyParam2=BodyValue2";
[urlRequest setHTTPBody: [body dataUsingEncoding: NSUTF8StringEncoding]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection
sendAsynchronousRequest: urlRequest
queue: queue
completionHandler: ^(NSURLResponse *response,
NSData *data,
NSError *error) {
if ([data length] >0 &&
error == nil){
NSString *html = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
NSLog(@"HTML = %@", html);
}
else if ([data length] == 0 &&
error == nil){
NSLog(@"Nothing was downloaded.");
}
else if (error!= nil){
NSLog(@"Error happened = %@", error);
}
}];
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Первый параметр, пересылаемый в теле HTTP, не обязательно предварять вопросительным знаком, а пересылаемый в строке запроса — обязательно.
11.9. Сериализация массивов и словарей в JSON
Постановка задачи
Необходимо сериализовать словарь или массив в объект JSON, который можно передавать по сети или просто сохранять на диск.
Решение
Воспользуйтесь методом dataWithJSONObject: options: error: класса NSJSONSerialization.
Обсуждение
Метод dataWithJSONObject: options: error: класса NSJSONSerialization может сериализовывать словари и массивы, в которых содержатся лишь экземпляры переменных NSString, NSNumber, NSArray, NSDictionary либо NSNull для нулевых значений. Как было указано ранее, объект, передаваемый этому методу, должен быть либо массивом, либо словарем.
Теперь создадим простой массив с несколькими ключами и значениями:
NSDictionary *dictionary =
@{
@"First Name": @"Anthony",
@"Last Name": @"Robbins",
@"Age": @51,
@"children": @[
@"Anthony's Son 1",
@"Anthony's Daughter 1",
@"Anthony's Son 2",
@"Anthony's Son 3",
@"Anthony's Daughter 2"
],
};
Как видите, в этом словаре содержатся имя, фамилия и возраст Энтони Роббинса. Ключ словаря, называемый children, содержит имена детей Энтони. Это массив строк, где каждой строкой представлен один ребенок. Итак, на данный момент переменная dictionary содержит все значения, которые мы хотели в нее поместить. Теперь нужно сериализовать ее в объект JSON:
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject: dictionary
options: NSJSONWritingPrettyPrinted
error:&error];
if ([jsonData length] > 0 &&
error == nil){
NSLog(@"Successfully serialized the dictionary into data = %@", jsonData);
}
else if ([jsonData length] == 0 &&
error == nil){
NSLog(@"No data was returned after serialization.");
}
else if (error!= nil){
NSLog(@"An error happened = %@", error);
}
Возвращаемым значением метода dataWithJSONObject: options: error: являются данные типа NSData. Правда, эти данные можно просто преобразовать в строку и вывести на консоль. Для этого применяется метод-инициализатор initWithData: encoding: класса NSString. Далее приведен полный пример, в котором словарь преобразуется в объект JSON. Этот объект превращается в строку, а строка выводится в окне консоли:
— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSDictionary *dictionary =
@{
@"First Name": @"Anthony",
@"Last Name": @"Robbins",
@"Age": @51,
@"children": @[
@"Anthony's Son 1",
@"Anthony's Daughter 1",
@"Anthony's Son 2",
@"Anthony's Son 3",
@"Anthony's Daughter 2"
],
};
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject: dictionary
options: NSJSONWritingPrettyPrinted
error:&error];
if ([jsonData length] > 0 &&
error == nil){
NSLog(@"Successfully serialized the dictionary into data.");
NSString *jsonString = [[NSString alloc] initWithData: jsonData
encoding: NSUTF8StringEncoding];
NSLog(@"JSON String = %@", jsonString);
}
else if ([jsonData length] == 0 &&
error == nil){
NSLog(@"No data was returned after serialization.");
}
else if (error!= nil){
NSLog(@"An error happened = %@", error);
self.window = [[UIWindow alloc]
initWithFrame: [[UIScreen mainScreen] bounds]];
// Точка переопределения для дополнительной настройки после запуска приложения
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Запустив это приложение, вы увидите в окне консоли следующие результаты:
Successfully serialized the dictionary into data.
JSON String = {
«Last Name»: «Robbins»,
«First Name»: «Anthony»,
«children»: [
«Anthony's Son 1»,
«Anthony's Daughter 1»,
«Anthony's Son 2»,
«Anthony's Son 3»,
«Anthony's Daughter 2»
],
«Age»: 51
}
11.10. Десериализация нотации JSON в массивы и словари
Постановка задачи
Имеются данные в формате JSON, их необходимо десериализовать в словарь или массив.
Решение
Воспользуйтесь методом JSONObjectWithData: options: error: класса NSJSONSerialization.
Обсуждение
Если вы уже сериализовали ваш словарь или массив в объект JSON (заключенный в экземпляре NSData, см. раздел 11.9), то эти данные нужно будет десериализовать обратно в словарь или массив. Это делается с помощью метода JSONObjectWithData: options: error:, относящегося к классу NSJSONSerialization. Объект, возвращаемый этим методом, будет представлять собой либо словарь, либо массив в зависимости от того, какие данные ему были переданы. Рассмотрим пример: