【问题标题】:Simple objective-c GET request简单的objective-c GET请求
【发布时间】:2012-02-22 22:24:51
【问题描述】:

这里的大部分信息是指被放弃的 ASIHTTPREQUEST 项目,请原谅我再次询问。

实际上,我需要刷磁条并将磁道 2 数据发送到返回“已注册”或“未注册”的网络服务(取决于卡的状态...)

所以我的数据很简单

NSData *data = [notification object];

然后我需要将它传递给一个 url 的顺序

http://example.com/CardSwipe.cfc?method=isenrolled&track2=data

然后只是收到一个响应字符串...

我已经搜索了很多,关于是否应该简单地使用 AFNetworking、RESTkit 还是使用本机 NSURL/NSMutableURLRequest 协议来完成,似乎有一些相互矛盾的答案。

【问题讨论】:

    标签: objective-c http get


    【解决方案1】:

    在 Objective-C 中执行 HTTP 请求的选项可能有点吓人。对我来说效果很好的一种解决方案是使用NSMutableURLRequest。一个例子(使用 ARC,所以 YMMV)是:

    - (NSString *) getDataFrom:(NSString *)url{
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setHTTPMethod:@"GET"];
        [request setURL:[NSURL URLWithString:url]];
    
        NSError *error = nil;
        NSHTTPURLResponse *responseCode = nil;
    
        NSData *oResponseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
    
        if([responseCode statusCode] != 200){
            NSLog(@"Error getting %@, HTTP status code %i", url, [responseCode statusCode]);
            return nil;
        }
    
        return [[NSString alloc] initWithData:oResponseData encoding:NSUTF8StringEncoding]; 
    }
    

    更新:

    您的问题标题和标记为 POST,但您的示例 URL 将指示 GET 请求。在 GET 请求的情况下,上面的例子就足够了。对于 POST,您可以按如下方式进行更改:

    - (NSString *) getDataFrom:(NSString *)url withBody:(NSData *)body{
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:body];
        [request setValue:[NSString stringWithFormat:@"%d", [body length]] forHTTPHeaderField:@"Content-Length"];
        [request setURL:[NSURL URLWithString:url]];
    
        /* the same as above from here out */ 
    }
    

    【讨论】:

    • 好的,感谢您的快速响应。我有点困惑这究竟是如何传递任何数据的?看起来像一个简单地连接到 http 服务的函数?
    • POST 样本通过[request setHTTPBody:body] 行传递数据并到达HTTP 正文。 GET 示例将在 URL 上传递数据,因此您必须提前格式化您的 URL……也许使用[NSString stringWithFormat:@"http://example.com?param1=%@&param2=%@", param1, param2]
    • 所以这将“
      Enrolled
      ”返回到 NSLOG与页面源相同。实际页面正在输出 Enrolled。我想这是一个微不足道的区别,因为我可以解析其他所有内容,但是这段代码是返回页面数据而不是正确的输出吗?
    • 我的建议是使用像 CF-Networking 或 ASIHttpRequest(虽然不符合 ARC)这样的框架来完成此类工作。
    • @JenScott,此代码仅返回所有内容。您的问题表明您想要一个响应字符串,并且此代码实际上会返回 Web 服务器返回的所有内容...如果我正在解析 JSON,我经常将此技术与 SBJson 或其他适当的库结合使用。
    【解决方案2】:

    iOS 9 更新: 因此,[NSURLConnection sendSynchronousRequest] 从 iOS 9 开始已被弃用。以下是从 iOS 9 开始使用 NSURLSession 执行 GET 请求的方法

    GET 请求

    // making a GET request to /init
    NSString *targetUrl = [NSString stringWithFormat:@"%@/init", baseUrl];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setHTTPMethod:@"GET"];
    [request setURL:[NSURL URLWithString:targetUrl]];
    
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
      ^(NSData * _Nullable data,
        NSURLResponse * _Nullable response,
        NSError * _Nullable error) {
    
          NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
          NSLog(@"Data received: %@", myString);
    }] resume];
    

    POST 请求

    // making a POST request to /init
    NSString *targetUrl = [NSString stringWithFormat:@"%@/init", baseUrl];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    
    //Make an NSDictionary that would be converted to an NSData object sent over as JSON with the request body
    NSDictionary *tmp = [[NSDictionary alloc] initWithObjectsAndKeys:
                         @"basic_attribution", @"scenario_type",
                         nil];
    NSError *error;
    NSData *postData = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&error];
    
    [request setHTTPBody:postData];
    [request setHTTPMethod:@"POST"];
    [request setURL:[NSURL URLWithString:targetUrl]];
    
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
      ^(NSData * _Nullable data,
        NSURLResponse * _Nullable response,
        NSError * _Nullable error) {
    
          NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
          NSLog(@"Data received: %@", responseStr);
    }] resume];
    

    【讨论】:

    • 刚刚在 iOS 13 的 Xcode 11 上的一个新项目(在整个项目范围内启用了 ARC)中为 GET 示例尝试了一些非常相似的方法(只是插入一个我知道会输出有效数据的网站);带有“线程 1:EXC_BAD_ACC”的炸弹 - 其他人尝试这个或重新编译现有项目?
    【解决方案3】:

    测试 100% 正常工作

    仅适用于目标 C

    -(void)fetchData
    {
    
        NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration];
    
        // Setup the request with URL
        NSURL *url = [NSURL URLWithString:@"https://test.orgorg.net/ios/getStory.php?"];
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
    
        // Convert POST string parameters to data using UTF8 Encoding
        NSString *postParams = @"";
        NSData *postData = [postParams dataUsingEncoding:NSUTF8StringEncoding];
    
        // Convert POST string parameters to data using UTF8 Encoding
        [urlRequest setHTTPMethod:@"POST"];
        [urlRequest setHTTPBody:postData];
    
        // Create dataTask
        NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    
            NSDictionary *results = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
            //JSON Parsing....
            NSString *message = results[@"Message"];
            BOOL status = results[@"Status"];
            if (status){
               // Here you go for data....
    
            }else{
                UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"App"
                                                                               message:message
                                                                        preferredStyle:UIAlertControllerStyleAlert]; // 1
                UIAlertAction *firstAction = [UIAlertAction actionWithTitle:@"Ok"
                                                                      style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
                                                                          NSLog(@"You pressed button one");
                                                                      }]; // 2
    
    
                [alert addAction:firstAction]; // 4
    
                [self presentViewController:alert animated:YES completion:nil];
            }
    
    
    
        }];
    
        // Fire the request
        [dataTask resume];
    }
    

    【讨论】:

    • 只有一种方法,是最简单的解决方案。
    【解决方案4】:
    **Simply Call and get your JSON Data.**
    
    -(void)getJSONData
    {
    
    NSURL *url = [NSURL URLWithString:@"http://itunes.apple.com/us/rss/topaudiobooks/limit=10/json"];
    
    NSURLSession *session = [NSURLSession sharedSession];
    
    NSURLSessionDataTask *data = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
        NSError *erro = nil;
    
        if (data!=nil) {
    
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&erro ];
    
            if (json.count > 0) {
    
                for(int i = 0; i<10 ; i++){
    
                    [arr addObject:[[[json[@"feed"][@"entry"] objectAtIndex:i]valueForKeyPath:@"im:image"] objectAtIndex:0][@"label"]];
               }
    
            }
        }
        dispatch_sync(dispatch_get_main_queue(),^{
    
            [table reloadData];
        });
    }];
    
    [data resume];
    }
    

    【讨论】:

      【解决方案5】:

      对于目标 c:

      -(void)loadData:(NSString*)url{
      NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
      [request setURL:[NSURL URLWithString:@"https://jsonplaceholder.typicode.com/posts"]];
      [request setHTTPMethod:@"GET"];
      
      
      NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
      [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
          NSMutableArray *jsonArray = (NSMutableArray *)[NSJSONSerialization JSONObjectWithData:data options:NSASCIIStringEncoding error:&error];
          if([self.delegate respondsToSelector:@selector(loadingData:)]){
              
              [self.delegate loadingData:jsonArray];
          }
      }] resume];
      

      }

      斯威夫特 5.5:

          // MARK: - Posts
      func getPosts(endPath : String, completion: @escaping ([Post]) -> ()) {
          let urlPath = Constants.Network.BASE_URL + endPath
          guard let url = URL(string: urlPath) else {
              print("Invalid URL")
              return
          }
          var request = URLRequest(url: url)
          request.httpMethod = Constants.Network.HTTPS_METHOD
          URLSession.shared.dataTask(with: request) { data, response, error in
              if let data = data {
                  if let decodedResponse = try? JSONDecoder().decode([Post].self, from: data) {
                      DispatchQueue.main.async {
                          completion(decodedResponse)
                      }
                      return
                  }
              }
              print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
          }.resume()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-02
        • 2021-03-12
        • 2013-08-30
        • 2019-12-26
        • 2015-03-15
        • 1970-01-01
        • 2015-07-25
        • 1970-01-01
        相关资源
        最近更新 更多