pyobjus/examples/delegate.py

43 lines
1.4 KiB
Python
Raw Normal View History

Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
"""
This example simplifies the code from the URL Loading System Programming Guide
(http://goo.gl/JJ2Q8T). It uses NSURLConnection to request an invalid connection
and get the connection:didFailWithError: delegate method triggered.
"""
from kivy.app import App
from kivy.uix.widget import Widget
from pyobjus import autoclass, protocol, objc_str
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
from pyobjus.dylib_manager import load_framework, INCLUDE
load_framework(INCLUDE.AppKit)
load_framework(INCLUDE.Foundation)
NSURL = autoclass('NSURL')
NSURLConnection = autoclass('NSURLConnection')
NSURLRequest = autoclass('NSURLRequest')
class DelegateApp(App):
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
def build(self):
self.request_connection()
return Widget()
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
def request_connection(self):
# This method request connection to an invalid URL so the
# connection_didFailWithError_ protocol method will be triggered.
url = NSURL.URLWithString_(objc_str('abc'))
request = NSURLRequest.requestWithURL_(url)
# Converts the Python delegate object to Objective C delegate instance
# simply by calling the objc_delegate() function.
connection = NSURLConnection.connectionWithRequest_delegate_(
request, self)
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
return connection
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
@protocol('NSURLConnectionDelegate')
def connection_didFailWithError_(self, connection, error):
print("Protocol method got called!!", connection, error)
Implements Objective C delegate support. The delegate support is achieved by a objc_delegate() function that converts a Python object to the corresponded Objective C delegate instance. A list of protocols intended to conform are also passed to the objc_delegate() function. The objc_delegate() dynamically creates a new Objective C class inherited by NSObject, then adds desired protocols methods and instantiates the instance. The instance is converted to Python object before returned so it can be passed to other MetaObjcClass methods that requires delegate instance. In order to achieve dynamic implementation of protocol methods. A `delegate_register` dict is added to remember the class name and corresponded Python object. So the dynamic function can dispatch the call to real Python object's method. However, currently registered delegates won't get released. Still looking for a way to free unused objects. This commit also adds an example at exampls/delegate.py. However, because the protocol method will be called asynchronously. I needs to write the example as a simple Kivy app so the execution won't quit before the protocol instance gets called. There may be a simpler way to implement a event loop but I failed. There is another problem about dynamically creating an Objective C class. That is, we need to use the objc_getProtocol() runtime function to find interested protocol methods (for signature and types). However, it seems not all protocols can be found through this function. More information about this issue can be found here: http://goo.gl/zA116F Signed-off-by: Olli Wang <olliwang@ollix.com>
2014-01-30 18:00:41 +00:00
if __name__ == "__main__":
DelegateApp().run()