0
# Class Enhancement and Convenience Functions
1
2
Functions for enhancing Objective-C classes with additional Python functionality, registering Abstract Base Classes, and adding convenience methods for better Python integration.
3
4
## Capabilities
5
6
### Class Method Enhancement
7
8
Functions for adding convenience methods and Python functionality to existing Objective-C classes.
9
10
```python { .api }
11
def addConvenienceForClass(classname, methods):
12
"""
13
Add Python methods to an Objective-C class.
14
15
Args:
16
classname (str): Name of the Objective-C class to enhance
17
methods (dict): Dictionary mapping method names to functions
18
19
Enhances the specified class with additional Python methods
20
that integrate seamlessly with existing Objective-C functionality.
21
"""
22
```
23
24
### Abstract Base Class Registration
25
26
Function for registering Python Abstract Base Classes with Objective-C classes for better type checking and polymorphism.
27
28
```python { .api }
29
def registerABCForClass(classname, *abc_class):
30
"""
31
Register Abstract Base Class for an Objective-C class.
32
33
Args:
34
classname (str): Name of the Objective-C class
35
*abc_class: One or more ABC classes to register
36
37
Enables isinstance() and issubclass() checks between
38
Objective-C classes and Python ABCs.
39
"""
40
```
41
42
### Method Availability Control
43
44
Functions for controlling method availability and argument handling.
45
46
```python { .api }
47
def registerUnavailableMethod(classname, selector):
48
"""
49
Mark a selector as unavailable on a class.
50
51
Args:
52
classname (str): Name of the Objective-C class
53
selector (str): Selector to mark as unavailable
54
55
Prevents access to specific methods that may be inappropriate
56
or dangerous when called from Python.
57
"""
58
59
def registerNewKeywords(classname, keywords, methodname):
60
"""
61
Register keyword arguments for __new__ method.
62
63
Args:
64
classname (str): Name of the Objective-C class
65
keywords (list): List of keyword argument names
66
methodname (str): Method name for initialization
67
68
Enables Python-style keyword arguments for object creation.
69
"""
70
71
def registerNewKeywordsFromSelector(classname, selector):
72
"""
73
Generate keyword arguments from selector signature.
74
75
Args:
76
classname (str): Name of the Objective-C class
77
selector (str): Selector to analyze for keyword generation
78
79
Automatically creates keyword arguments based on selector names.
80
"""
81
```
82
83
### Collection Convenience Functions
84
85
Functions for adding Python-style convenience methods to Objective-C collection classes.
86
87
```python { .api }
88
def addConvenienceForBasicMapping(name, readonly=False):
89
"""
90
Add mapping convenience methods to a class.
91
92
Args:
93
name (str): Class name to enhance
94
readonly (bool): Whether mapping should be read-only
95
96
Adds Python dict-like methods (__getitem__, __setitem__, etc.)
97
to Objective-C classes that represent key-value collections.
98
"""
99
100
def addConvenienceForBasicSequence(name, readonly=False):
101
"""
102
Add sequence convenience methods to a class.
103
104
Args:
105
name (str): Class name to enhance
106
readonly (bool): Whether sequence should be read-only
107
108
Adds Python list-like methods (__getitem__, __setitem__, __len__, etc.)
109
to Objective-C classes that represent ordered collections.
110
"""
111
```
112
113
**Usage Examples:**
114
115
```python
116
import objc
117
from objc import (addConvenienceForClass, registerABCForClass,
118
registerUnavailableMethod, addConvenienceForBasicSequence)
119
from collections.abc import Sequence, MutableSequence
120
121
# Add convenience methods to NSString
122
def python_split(self, separator=" "):
123
"""Add Python-style split method to NSString."""
124
return str(self).split(separator)
125
126
def python_strip(self):
127
"""Add Python-style strip method to NSString."""
128
return str(self).strip()
129
130
addConvenienceForClass("NSString", {
131
"split": python_split,
132
"strip": python_strip
133
})
134
135
# Now NSString instances have Python-style methods
136
ns_string = objc.lookUpClass("NSString").stringWithString_(" hello world ")
137
parts = ns_string.split(" ") # ['', '', 'hello', 'world', '', '']
138
clean = ns_string.strip() # "hello world"
139
140
# Register ABC for better type checking
141
registerABCForClass("NSArray", Sequence)
142
registerABCForClass("NSMutableArray", MutableSequence)
143
144
# Now isinstance checks work
145
ns_array = objc.lookUpClass("NSArray").arrayWithObjects_("a", "b", "c")
146
print(isinstance(ns_array, Sequence)) # True
147
148
ns_mutable = objc.lookUpClass("NSMutableArray").arrayWithObjects_("x", "y")
149
print(isinstance(ns_mutable, MutableSequence)) # True
150
151
# Mark dangerous methods as unavailable
152
registerUnavailableMethod("NSFileManager", "removeItemAtPath:error:")
153
154
# Add sequence convenience to custom collection class
155
addConvenienceForBasicSequence("MyCustomArray", readonly=False)
156
157
# Register keyword arguments for cleaner object creation
158
registerNewKeywords("NSRect", ["x", "y", "width", "height"], "__new__")
159
160
# Now can create with keywords (if properly implemented)
161
# rect = NSRect(x=10, y=20, width=100, height=50)
162
```
163
164
### Enhanced Integration Patterns
165
166
Common patterns for enhancing Objective-C classes:
167
168
```python
169
# Pattern 1: Adding Python idioms to Objective-C collections
170
def enhance_nsarray():
171
def python_contains(self, item):
172
"""Add 'in' operator support."""
173
return self.containsObject_(item)
174
175
def python_iter(self):
176
"""Add iterator support."""
177
for i in range(self.count()):
178
yield self.objectAtIndex_(i)
179
180
addConvenienceForClass("NSArray", {
181
"__contains__": python_contains,
182
"__iter__": python_iter
183
})
184
185
enhance_nsarray()
186
187
# Now NSArray works more like Python lists
188
ns_array = objc.lookUpClass("NSArray").arrayWithObjects_("a", "b", "c")
189
print("b" in ns_array) # True
190
for item in ns_array: # Iteration works
191
print(item)
192
193
# Pattern 2: Adding utility methods
194
def enhance_nsurl():
195
def to_path(self):
196
"""Convert NSURL to pathlib.Path."""
197
from pathlib import Path
198
return Path(self.path())
199
200
def read_text(self):
201
"""Read URL content as text."""
202
data = objc.lookUpClass("NSData").dataWithContentsOfURL_(self)
203
if data:
204
return str(data, 'utf-8')
205
return None
206
207
addConvenienceForClass("NSURL", {
208
"to_path": to_path,
209
"read_text": read_text
210
})
211
212
enhance_nsurl()
213
214
# Usage with enhanced NSURL
215
file_url = objc.lookUpClass("NSURL").fileURLWithPath_("/tmp/test.txt")
216
path = file_url.to_path() # Returns pathlib.Path object
217
content = file_url.read_text() # Read file content
218
```
219
220
### Best Practices
221
222
- **Non-conflicting Names**: Use descriptive names that don't conflict with existing methods
223
- **Python Conventions**: Follow Python naming and behavior conventions
224
- **Error Handling**: Include proper error handling in convenience methods
225
- **Documentation**: Document added methods for clarity
226
- **Performance**: Consider performance implications of convenience methods