omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Use objc_util and NSURLConnection to make a GET request

    Pythonista
    3
    8
    6146
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • tlinnet
      tlinnet last edited by

      Hi.

      Since pythonista does not handle ipv6, I would like to make a method for objc_util, that can be a replacement for python request.

      A objc_util replacement for a call like this:

      import requests
      
      root='http://validate.jsontest.com'
      url=root+''
      params = {'json':str({"key":"value"})}
      r = requests.get(url, params=params)
      print r.json()
      
      1 Reply Last reply Reply Quote 0
      • tlinnet
        tlinnet last edited by

        I am here at the moment

        from objc_util import *
        
        class Web(object):
            def __init__(self, root=None, method=None, headers=None):
                #NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
                self.request = ObjCClass('NSMutableURLRequest').alloc().initWithURL_(nsurl(root))
                #[request setHTTPMethod:@"POST"];
                self.request.setHTTPMethod_(method)
        
                # Make headers
                for key in headers:
                    #[request setValue:@"es" forHTTPHeaderField:@"Accept-Language"];
                    self.request.setValue_forHTTPHeaderField_(key, headers[key])
        
                # Make request
                #NSURLConnection * theConnection = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self];
                #self.conn = ObjCClass('NSURLConnection').alloc().initWithRequest_delegate_(self.request, self)
                self.conn = ObjCClass('NSURLConnection').alloc().initWithRequest_delegate_startImmediately_(self.request, self, True)
        
                #[connection autorelease];
                self.conn.autorelease()
        

        But I dont know how to unpack or return the request?
        So I get the response from the server?

        1 Reply Last reply Reply Quote 0
        • lukaskollmer
          lukaskollmer last edited by

          NSURLConnection was deprecated with iOS 9. However, you can use its replacement, NSURLSession.

          This is a very basic example of how to use NSURLSession with parameters and how to get the response.
          You can pass your parameters as a dictionary as second argument to the validate method.
          I think @omz advised against using objc_util.retain_global, but it's necessary in this example to prevent the block from getting released before its getting called by the URL session.

          In a proper implementation, you probably want to create a Python class so that you can store the completion handler.

          #!/usr/bin/env python3
          import objc_util
          import urllib.parse
          from ctypes import c_void_p
          
          NSURLRequest = objc_util.ObjCClass("NSURLRequest")
          NSURLSession = objc_util.ObjCClass("NSURLSession")
          NSURLSessionConfiguration = objc_util.ObjCClass("NSURLSessionConfiguration")
          
          
          def validate(url, params, responseHandler):
          	if params:
          		params_encoded = urllib.parse.urlencode(params)
          	else:
          		params_encoded = ""
          	url = objc_util.nsurl("{}?{}".format(url, params_encoded))
          	request = NSURLRequest.request(URL=url)
          	configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
          	
          	session = NSURLSession.session(Configuration=configuration)
          	
          	completionHandler = objc_util.ObjCBlock(responseHandler, restype=None, argtypes=[c_void_p, c_void_p, c_void_p, c_void_p])
          	objc_util.retain_global(completionHandler)
          	
          	dataTask = session.dataTask(Request=request, completionHandler=completionHandler)
          	dataTask.resume()
          
          def responseHandlerBlock(_cmd, data, response, error):
          	if error is not None:
          		error = objc_util.ObjCInstance(error)
          		print(error)
          		return
          	response = objc_util.ObjCInstance(response)
          	data = objc_util.ObjCInstance(data)
          	print(str(objc_util.nsdata_to_bytes(data)))
          
          url = "http://validate.jsontest.com"
          params = {"json" : {"first" : "lukas", "last" : "kollmer"}}
          
          validate(url, None, responseHandlerBlock)
          
          1 Reply Last reply Reply Quote 0
          • tlinnet
            tlinnet last edited by

            WOW!!!!

            Thanks! :)
            This works as expected. :)

            I get a json back, I can work with.
            I will try to implement this, and see if it passes the Apple review.

            Thanks!

            import objc_util
            from urlparse import urlparse
            from urllib import urlencode
            from ctypes import c_void_p
            
            NSURLRequest = objc_util.ObjCClass("NSURLRequest")
            NSURLSession = objc_util.ObjCClass("NSURLSession")
            NSURLSessionConfiguration = objc_util.ObjCClass("NSURLSessionConfiguration")
            
            def validate(url, params, responseHandler):
                if params:
                    params_encoded = urlencode(params)
                else:
                    params_encoded = ""
                url = objc_util.nsurl("{}?{}".format(url, params_encoded))
                request = NSURLRequest.request(URL=url)
                configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
                
                session = NSURLSession.session(Configuration=configuration)
                
                completionHandler = objc_util.ObjCBlock(responseHandler, restype=None, argtypes=[c_void_p, c_void_p, c_void_p, c_void_p])
                objc_util.retain_global(completionHandler)
                
                dataTask = session.dataTask(Request=request, completionHandler=completionHandler)
                dataTask.resume()
            
            def responseHandlerBlock(_cmd, data, response, error):
                if error is not None:
                    error = objc_util.ObjCInstance(error)
                    print(error)
                    return
                response = objc_util.ObjCInstance(response)
                data = objc_util.ObjCInstance(data)
                print(str(objc_util.nsdata_to_bytes(data)))
            
            url = "http://validate.jsontest.com"
            params = {"json" : {"first" : "lukas", "last" : "kollmer"}}
            
            #validate(url, None, responseHandlerBlock)
            validate(url, params, responseHandlerBlock)
            
            1 Reply Last reply Reply Quote 0
            • tlinnet
              tlinnet last edited by

              Now getting a return.

              Don't know how to exactly to implement a "wait", but here is a try

              import objc_util
              from urlparse import urlparse
              from urllib import urlencode
              from ctypes import c_void_p
              import time
              
              class Web(object):
                  def __init__(self, url=None, params=None):
                      self.data = None
              
                      if params:
                          params_encoded = urlencode(params)
                      else:
                          params_encoded = ""
                      url = objc_util.nsurl("{}?{}".format(url, params_encoded))
                      request = objc_util.ObjCClass("NSURLRequest").request(URL=url)
                      configuration = objc_util.ObjCClass("NSURLSessionConfiguration").defaultSessionConfiguration()
                  
                      session = objc_util.ObjCClass("NSURLSession").session(Configuration=configuration)
                  
                      completionHandler = objc_util.ObjCBlock(self.responseHandlerBlock, restype=None, argtypes=[c_void_p, c_void_p, c_void_p, c_void_p])
                      objc_util.retain_global(completionHandler)
                  
                      dataTask = session.dataTask(Request=request, completionHandler=completionHandler)
                      dataTask.resume()
              
                  def responseHandlerBlock(self, _cmd, data, response, error):
                      if error is not None:
                          error = objc_util.ObjCInstance(error)
                          print(error)
                          return
                      response = objc_util.ObjCInstance(response)
                      data = objc_util.ObjCInstance(data)
                      self.data = (str(objc_util.nsdata_to_bytes(data)))
              
                  def return_data(self):
                      return self.data
              
              
              url = "http://validate.jsontest.com"
              params = {"json" : {"first" : "lukas", "last" : "kollmer"}}
              
              #validate(url, None, responseHandlerBlock)
              #validate(url, params, responseHandlerBlock)
              call = Web(url, params)
              
              wait = True
              while wait:
                  data = call.return_data()
                  if data != None:
                      print data
                      wait = False
              print "Done"```
              1 Reply Last reply Reply Quote 0
              • tlinnet
                tlinnet last edited by

                I got it to work with, headers, ios basic authentication and parameters, and saving the response.

                Thanks!

                https://gist.github.com/tlinnet/31b35136e206ea2b4829a13799c89316

                1 Reply Last reply Reply Quote 0
                • tlinnet
                  tlinnet last edited by

                  And now the last modification..

                  Making exceptions work as well.

                  https://gist.github.com/tlinnet/aff5decf31d07d0c0cccfad7961353f7

                  1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB last edited by

                    If your app is doing a lot of this, be careful that there may be a memory leak. you may need to use someobject ._cached_methods.clear() for every ObjCInstance that you create inside the callback, which breaks a reference cycle (well, at least untangles it a bit so gc can handle it)

                    1 Reply Last reply Reply Quote 1
                    • First post
                      Last post
                    Powered by NodeBB Forums | Contributors