Module: OSX

Defined in:
src/ruby/osx/objc/cocoa_macros.rb,
src/ruby/osx/objc/application.rb,
src/ruby/osx/objc/cocoa_macros_appkit.rb,
src/ruby/osx/objc/oc_attachments_appkit.rb,
src/ruby/osx/objc/oc_bundle_support.rb,
src/ruby/osx/objc/oc_exception.rb,
src/ruby/osx/objc/oc_import.rb,
src/ruby/osx/objc/oc_wrapper.rb,
src/ruby/osx/objc/ruby_addition.rb,
src/objc/mdl_osxobjc.m

Overview

Namespace for RubyCocoa and Objective-C classes, such as OSX::NSString, OSX::NSView, …

Defined Under Namespace

Modules: BundleSupport, CoreData, NSBehaviorAttachment, NSKVCAccessorUtil, NSKVCBehaviorAttachment, NSKeyValueCodingAttachment, OCClsWrapper, OCObjWrapper Classes: Boxed, NSApplication, NSBundle, NSData, NSImage, NSMutableData, NSPoint, NSRange, NSRect, NSSize, OCDataConvException, OCException, OCMessageSendException, ObjcID, ObjcPtr

Constant Summary

APP_DIR =

Fullpath of running application.

File.expand_path(File.dirname($0)).
split(File::SEPARATOR)[0..-3].join(File::SEPARATOR)
RSRC_DIR =

Fullpath of “Resources” directory in running application.

File.join(APP_DIR, 'Contents', 'Resources')
APP_BUNDLE =

OSX::NSBundle of running application.

NSBundle.bundleWithPath(APP_DIR)
FRAMEWORK_PATHS =

framework search paths.

[
  '/System/Library/Frameworks',
  '/Library/Frameworks'
]
SIGN_PATHS =

bridgesupport file search paths.

[
  '/System/Library/BridgeSupport', 
  '/Library/BridgeSupport'
]
PRE_SIGN_PATHS =

additional bridgesupport file search paths by environment 'BRIDGE_SUPPORT_PATH'.

if path = ENV['BRIDGE_SUPPORT_PATH']
  path.split(':')
else
  []
end
QUICK_FRAMEWORKS =

A name-to-path cache for the frameworks we support that are buried into umbrella frameworks.

{
  'CoreGraphics' => '/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework',
  'PDFKit' => '/System/Library/Frameworks/Quartz.framework/Frameworks/PDFKit.framework',
  'QuartzComposer' => '/System/Library/Frameworks/Quartz.framework/Frameworks/QuartzComposer.framework',
  'ImageKit' => '/System/Library/Frameworks/Quartz.framework/Frameworks/ImageKit.framework'
}
RUBYCOCOA_VERSION =

The RubyCocoa version string

rb_obj_freeze(rb_str_new2(RUBYCOCOA_VERSION))
RUBYCOCOA_RELEASE_DATE =

The release date string

rb_obj_freeze(rb_str_new2(RUBYCOCOA_RELEASE_DATE))
RUBYCOCOA_SVN_REVISION =

The release revision string

rb_obj_freeze(rb_str_new2(RUBYCOCOA_SVN_REVISION))
RUBYCOCOA_BUILD_LP64 =

Whether built for LP64 or not

Qfalse
RUBYCOCOA_RESOURCES_PATH =

Path to Resources directory of RubyCocoa.framework

rb_obj_freeze(rb_str_new2(p))
RUBYCOCOA_SIGN_PATHS =

bridgesupport search paths at OSX.require_framework()

rb_ary_new()
RUBYCOCOA_FRAMEWORK_PATHS =

Framework search paths at OSX.require_framework() or OSX.load_bridge_support_signatures()

rb_ary_new()

Class Attribute Summary (collapse)

Localization (collapse)

Frameworks and BridgeSupport files (collapse)

Objective-C Classes and methods (collapse)

Class Method Summary (collapse)

Class Attribute Details

+ (Object) relaxed_syntax

If true (default), RubyCocoa allows to ommit last “_” of a method name.

Examples:

obj.aaa_Bbb_Ccc_(a0, a1, a2)  # strict style.
obj.aaa_Bbb_Ccc(a0, a1, a2)   # allowed when OSX.relaxed_syntax is true.


15
16
17
# File 'src/ruby/osx/objc/oc_wrapper.rb', line 15

def relaxed_syntax
  @relaxed_syntax
end

Class Method Details

+ (Object) __load_bridge_support_file__(dir, framework_name)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'src/ruby/osx/objc/oc_import.rb', line 132

def __load_bridge_support_file__(dir, framework_name)
  @bridge_support_signatures_loaded_marks ||= {}
  return true if @bridge_support_signatures_loaded_marks[framework_name]
  bs = File.join(dir, framework_name + '.bridgesupport')
  pbs = File.join(dir, framework_name + 'Private.bridgesupport')
  if File.exist?(bs) or File.exist?(pbs)
    # Load the .dylib first (if any).
    dylib = File.join(dir, framework_name + '.dylib')
    OSX.load_bridge_support_dylib(dylib) if File.exist?(dylib) 

    # Then the regular metadata file.
    OSX.load_bridge_support_file(bs) if File.exist?(bs)
  
    # And finally the private metadata file (if any).
    OSX.load_bridge_support_file(pbs) if File.exist?(pbs)
    return @bridge_support_signatures_loaded_marks[framework_name] = true
  end
  return false
end

+ (Object) __rebind_umethod__

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



439
440
441
442
443
444
445
446
447
448
# File 'src/objc/mdl_osxobjc.m', line 439

static VALUE
osx_mf_rebind_umethod(VALUE rcv, VALUE klass, VALUE umethod)
{
  struct RB_METHOD *data;

  Data_Get_Struct(umethod, struct RB_METHOD, data);
  data->rklass = klass;
  
  return Qnil;
}

+ (Array) _bundle_path_for_framework(framework)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns bundle and path for given framework name.

Parameters:

  • framework (String)

    a name of framework, such as “WebKit”.

Returns:

  • (Array)

    a pair of OSX::NSBundle and String.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'src/ruby/osx/objc/oc_import.rb', line 53

def _bundle_path_for_framework(framework)
  if framework[0] == ?/
    [OSX::NSBundle.bundleWithPath(framework), framework]
  elsif path = QUICK_FRAMEWORKS[framework]
    [OSX::NSBundle.bundleWithPath(path), path]
  else
    path = FRAMEWORK_PATHS.map { |dir| 
      File.join(dir, "#{framework}.framework") 
    }.find { |path| 
      File.exist?(path) 
    }
    if path
      [OSX::NSBundle.bundleWithPath(path), path]
    end
  end
end

+ (Boolean) _debug?

Whether prints debug information or not.

Returns:

  • (Boolean)


11
12
13
# File 'src/ruby/osx/objc/oc_exception.rb', line 11

def self._debug?
  ($DEBUG || $RUBYCOCOA_DEBUG)
end

+ (Object) _ignore_ns_override



181
182
183
184
185
# File 'src/objc/mdl_objwrapper.m', line 181

static VALUE
wrapper_ignore_ns_override (VALUE rcv)
{
  return ignore_ns_override ? Qtrue : Qfalse;
}

+ (Object) _ignore_ns_override=



187
188
189
190
191
192
# File 'src/objc/mdl_objwrapper.m', line 187

static VALUE
wrapper_ignore_ns_override_set (VALUE rcv, VALUE val)
{
  ignore_ns_override = RTEST(val);
  return val;
}

+ (Object) _objc_lookup_superclass(occls)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns super class of given Objecitve-C class.



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'src/ruby/osx/objc/oc_import.rb', line 302

def _objc_lookup_superclass(occls)
  occls_superclass = occls.oc_superclass
  if occls_superclass.nil? or occls_superclass.__ocid__ == occls.__ocid__ 
    OSX::ObjcID
  elsif occls_superclass.is_a?(OSX::NSProxy) or occls_superclass.__ocid__ == OSX::NSProxy.__ocid__
    OSX::NSProxy
  else
    begin
      OSX.const_get(occls_superclass.to_s.to_sym) 
    rescue NameError
      # some ObjC internal class cannot become Ruby constant
      # because of prefix '%' or '_'
      if occls.__ocid__ != occls_superclass.__ocid__
        OSX._objc_lookup_superclass(occls_superclass)
      else
        OSX::ObjcID # root class of ObjC
      end
    end
  end
end

+ (Class) class_new_for_occlass(occls)

create Ruby's class for Cocoa class

Parameters:

  • occls (Objective-C Class)

Returns:

  • (Class)


281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'src/ruby/osx/objc/oc_import.rb', line 281

def class_new_for_occlass(occls)
  superclass = _objc_lookup_superclass(occls)
  klass = Class.new(superclass)
  klass.class_eval do
    if superclass == OSX::ObjcID
      include OCObjWrapper 
      self.extend OCClsWrapper
    end
    @ocid = occls.__ocid__.to_i
  end
  if superclass == OSX::ObjcID
    def klass.__ocid__() @ocid end
    def klass.to_s() name end
    def klass.inherited(subklass) subklass.ns_inherited() end
  end
  return klass
end

+ (Object) const_missing(c)

Load C constants/classes lazily.



209
210
211
212
213
214
215
# File 'src/ruby/osx/objc/oc_import.rb', line 209

def self.const_missing(c)
  begin
    OSX::import_c_constant(c)
  rescue LoadError
    (OSX::ns_import(c) or raise NameError, "uninitialized constant #{c}")
  end
end

+ (Boolean) framework_loaded?(framework)

Returns whether a framework is loaded of not.

Parameters:

  • framework (String)

    a name of framework, such as “WebKit”.

Returns:

  • (Boolean)


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'src/ruby/osx/objc/oc_import.rb', line 112

def framework_loaded?(framework)
  bundle, path = _bundle_path_for_framework(framework)
  unless bundle.nil?
    loaded = bundle.isLoaded
    if loaded then
      load_bridge_support_signatures(path)
    else
      # CoreFoundation/Foundation are linked at built-time.
      id = bundle.bundleIdentifier
      loaded = (id.isEqualToString?('com.apple.CoreFoundation') or 
                id.isEqualToString?('com.apple.Foundation'))
    end
    loaded
  else
    raise ArgumentError, "Can't locate framework '#{framework}'"
  end
end

+ (Object) import_c_constant

Imports a C constant from loaded bridgesupport.

Parameters:

  • sym

    Name of constant

Returns:

  • A new constant imported



1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
# File 'src/objc/BridgeSupport.m', line 1973

static VALUE
osx_import_c_constant (VALUE self, VALUE sym)
{
  const char *      name;
  char *            real_name;
  struct bsConst *  bs_const;
  void *            cvalue;
  VALUE             value;
  
  name = rb_id2name(SYM2ID(sym));
  real_name = (char *)name;
  if (!st_lookup(bsConstants, (st_data_t)name, (st_data_t *)&bs_const)) {
    // Decapitalize the string and try again.
    real_name = strdup(name);
    DECAPITALIZE(real_name);
    if (!st_lookup(bsConstants, (st_data_t)real_name, (st_data_t *)&bs_const)) {
      free(real_name);
      rb_raise(rb_eLoadError, "C constant '%s' not found", name);
    }
  }

  if (bs_const->ignored)
    rb_raise(rb_eRuntimeError, "Constant '%s' is not supported (suggested alternative: '%s')", bs_const->name, bs_const->suggestion != NULL ? bs_const->suggestion : "n/a");

  cvalue = dlsym(RTLD_DEFAULT, real_name);
  value = Qnil;
  if (cvalue != NULL) {
    BS_LOG("Importing C constant `%s' of type '%s'", name, bs_const->encoding);
    if (bs_const->is_magic_cookie) { 
      struct bsCFType *bs_cftype;

      bs_cftype = find_bs_cf_type_by_encoding(bs_const->encoding);
      bs_const->class_name = bs_cftype != NULL
        ? bs_cftype->bridged_class_name : "OCObject";

      BS_LOG("Constant is a magic-cookie of fixed value %p, guessed class name '%s'", *(void **)cvalue, bs_const->class_name);

      st_insert(bsMagicCookieConstants, (st_data_t)*(void **)cvalue, (st_data_t)bs_const);
    }
    if (!ocdata_to_rbobj(Qnil, bs_const->encoding, cvalue, &value, NO))
      rb_raise(ocdataconv_err_class(), "Cannot convert the Objective-C constant '%s' as '%s' to Ruby", name, bs_const->encoding);
    rb_define_const(self, name, value);
    BS_LOG("Imported C constant `%s' with value %p", name, (void *)value);
  }

  if (name != real_name)
    free(real_name);
  
  if (cvalue == NULL)
    rb_bug("Can't locate constant symbol '%s' : %s", name, dlerror());
  
  return value;
}

+ (Object) included(m)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Overrides const_missing.



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'src/ruby/osx/objc/oc_import.rb', line 219

def self.included(m)
  if m.respond_to? :const_missing
    m.module_eval do
      class <<self
        alias_method :_osx_const_missing_prev, :const_missing
        def const_missing(c)
          begin
            OSX.const_missing(c)
          rescue NameError
            _osx_const_missing_prev(c)
          end
        end
      end
    end
  else
    m.module_eval do
      def self.const_missing(c)
        OSX.const_missing(c)
      end
    end
  end
end

+ (Object) init_for_bundle(args = nil) {|bundle, param, logger| ... }

Initializes RubyCocoa bundle from Cocoa applications. see sample/CocoaRepl/.

Examples:

OSX.init_for_bundle do |bundle, param, logger|
  require '...'
  # do something
end

Yields:

  • (bundle, param, logger)

    bundle and param values from Objective-C initilizer RBBundleInit().



63
64
65
# File 'src/ruby/osx/objc/oc_bundle_support.rb', line 63

def init_for_bundle(args = nil)
  BundleSupport.init_for_bundle(args) { |*x| yield(*x) }
end

+ (Object) load_bridge_support_dylib

Loads brdigesupport dylib. Recommends to use OSX.require_frmework in regular cases.

Parameters:

  • Path

    of bridgesupport dylib.

Returns:

  • nil



1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
# File 'src/objc/BridgeSupport.m', line 1106

static VALUE
osx_load_bridge_support_dylib (VALUE rcv, VALUE path)
{
  const char *cpath;

  cpath = StringValuePtr(path);
  if (dlopen(cpath, RTLD_LAZY) == NULL)
    rb_raise(rb_eArgError, "Can't load the bridge support dylib file `%s' : %s", cpath, dlerror());

  return Qnil;
}

+ (Moudule) load_bridge_support_file

Loads brdigesupport file. Recommends to use OSX.require_frmework in regular cases.

Parameters:

  • Path

    of bridgesupport file.

Returns:

  • (Moudule)

    Module OSX



1948
1949
1950
1951
1952
1953
# File 'src/objc/BridgeSupport.m', line 1948

static VALUE
osx_load_bridge_support_file (VALUE rcv, VALUE path)
{
  rb_warn("libxml2 is not available, bridge support file `%s' cannot be read", StringValuePtr(path));
  return rcv;
}

+ (Boolean) load_bridge_support_signatures(framework)

Loads BridgeSupport file of given framework.

Parameters:

  • framework (String)

    a name or fullpath of framework, such as “WebKit” or “/System/Library/Frameworks/WebKit.framework”.

Returns:

  • (Boolean)


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'src/ruby/osx/objc/oc_import.rb', line 157

def load_bridge_support_signatures(framework)
  # First, look into the pre paths.  
  fname = framework[0] == ?/ ? File.basename(framework, '.framework') : framework
  PRE_SIGN_PATHS.each { |dir| return true if __load_bridge_support_file__(dir, fname) }

  # A path to a framework, let's search for a BridgeSupport file inside the Resources folder.
  if framework[0] == ?/
    path = File.join(framework, 'Resources', 'BridgeSupport')
    if __load_bridge_support_file__(path, fname)
	Dir.glob(File.join(framework, 'Frameworks', '*.framework')).each do |subframework|
 OSX.load_bridge_support_signatures(subframework)
	end
      return true
    end
    framework = fname
  end
  
  # Let's try to localize the framework and see if it contains the metadata.
  FRAMEWORK_PATHS.each do |dir|
    path = File.join(dir, "#{framework}.framework")
    if File.exist?(path)
      bspath = File.join(path, 'Resources', 'BridgeSupport')
      if __load_bridge_support_file__(bspath, fname)
        Dir.glob(File.join(framework, 'Frameworks', '*.framework')).each do |subframework|
          OSX.load_bridge_support_signatures(subframework)
        end
        return true
      end
    end
  end

  # Try the app/bundle specific and RubyCocoa.framework metadata directories.
  RUBYCOCOA_SIGN_PATHS.each do |path| 
    if File.exist?(path) then
      return true if __load_bridge_support_file__(path, fname) 
    end
  end

  # We can still look into the general metadata directories. 
  SIGN_PATHS.each { |dir| return true if __load_bridge_support_file__(dir, fname) } 

  # Damnit!
  warn "Can't find signatures file for #{framework}" if OSX._debug?
  return false
end

+ (OSX::NSPropertyList) load_plist(data)

Returns property list from input data.

Parameters:

Returns:

  • (OSX::NSPropertyList)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'src/ruby/osx/objc/ruby_addition.rb', line 44

def load_plist(data)
  case data
  when String
    if RUBY_VERSION >= '2.0'
      if data.encoding == Encoding::ASCII_8BIT
        nsdata = OSX::NSData.dataWithBytes_length(data, data.bytesize)
      else
        str = data.encode!(Encoding::UTF_8).to_ns
        nsdata = str.dataUsingEncoding(OSX::NSUTF8StringEncoding)
      end
    else
      nsdata = OSX::NSData.dataWithBytes_length(data, data.length)
    end
  when OSX::NSString
    nsdata = data.dataUsingEncoding(OSX::NSUTF8StringEncoding)
  when OSX::NSData
    nsdata = data
  else
    raise ArgumentError, 'argument should be String, OSX::NSString or OSX::NSData'
  end
  obj, error = OSX::NSPropertyListSerialization.objc_send \
    :propertyListFromData, nsdata,
    :mutabilityOption, OSX::NSPropertyListImmutable,
    :format, nil,
    :errorDescription
  raise error.to_s if obj.nil?
  obj.respond_to?(:to_ruby) ? obj.to_ruby : obj
end

+ (Sting) lookup_informal_protocol_method_type

Finds type encoding of a given method from informal protocols.

Parameters:

  • sel

    Name of a method

  • is_class_method (Boolean)

    Whether the given method is a class method or not

Returns:

  • (Sting)

    Type encoding



2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
# File 'src/objc/BridgeSupport.m', line 2168

static VALUE
osx_lookup_informal_protocol_method_type (VALUE rcv, VALUE sel, 
  VALUE is_class_method)
{
  struct bsInformalProtocolMethod *method;

  method = find_bs_informal_protocol_method(StringValuePtr(sel), 
    RTEST(is_class_method));

  return method == NULL ? Qnil : rb_str_new2(method->encoding);
}

+ (Object) method_missing(mname, *args)

Backward compatibility check; get C constants



18
19
20
21
22
23
24
25
26
27
28
# File 'src/ruby/osx/objc/oc_wrapper.rb', line 18

def method_missing(mname, *args)
  if args.length == 0
    begin
      ret = const_get(mname)
      warn "#{caller[0]}: syntax 'OSX.#{mname}' to get the constant is deprecated and its use is discouraged, please use 'OSX::#{mname}' instead."
      return ret
    rescue
    end
  end
  super
end

+ (Object) ns_autorelease_pool

Like Objective-C “@autorelease { … }” block.

Examples:

OSX.ns_autorelease_pool do
    # do something
end


258
259
260
261
262
263
264
265
# File 'src/objc/mdl_osxobjc.m', line 258

static VALUE
ns_autorelease_pool(VALUE mdl)
{
  id pool = [[NSAutoreleasePool alloc] init];
  rb_yield(Qnil);
  [pool release];
  return Qnil;
}

+ (Class) ns_import(sym)

create Ruby's class for Cocoa class, then define Constant under module 'OSX'.

Parameters:

  • sym (Symbol, String)

    name of Objective-C class.

Returns:

  • (Class)


246
247
248
249
250
251
252
253
254
255
256
257
# File 'src/ruby/osx/objc/oc_import.rb', line 246

def ns_import(sym)
  if not OSX.const_defined?(sym)
    NSLog("importing #{sym}...") if OSX._debug?
    klass = if clsobj = NSClassFromString(sym)
      if rbcls = class_new_for_occlass(clsobj)
        OSX.const_set(sym, rbcls)
      end
    end
    NSLog("importing #{sym}... done (#{klass.ancestors.join(' -> ')})") if (klass and OSX._debug?)
    return klass
  end
end

+ (nil) ns_import_all

Runs ns_import for all Cococa classes. RubyCocoa invokes ns_import_all implicitly in require_framework.

Returns:

  • (nil)

Since:

  • 1.2.0



264
265
266
267
268
269
270
271
272
273
274
275
# File 'src/ruby/osx/objc/oc_import.rb', line 264

def ns_import_all
  OSX.objc_classnames do |klassname|
    # ignore private classes, such as starting with "_".
    if /\A[A-Z]/ =~ klassname
      if OSX.const_defined?(klassname)
 next
	end
	OSX.ns_import(klassname)
    end
  end
  return nil
end

+ (Object) NSLocalizedString(key, comment = nil)

Convenient function for -[NSBundle localizedStringForKey:value:table:] of mainBundle.



13
14
15
16
# File 'src/ruby/osx/objc/cocoa_macros.rb', line 13

def NSLocalizedString (key, comment = nil)
  OSX::NSBundle.mainBundle.
    localizedStringForKey_value_table(key, "", nil)
end

+ (Object) NSLocalizedStringFromTable(key, tbl, comment = nil)

Convenient function for -[NSBundle localizedStringForKey:value:table:] of mainBundle.



18
19
20
21
# File 'src/ruby/osx/objc/cocoa_macros.rb', line 18

def NSLocalizedStringFromTable (key, tbl, comment = nil)
  OSX::NSBundle.mainBundle.
    localizedStringForKey_value_table(key, "", tbl)
end

+ (Object) NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment = nil)

Convenient function for -[NSBundle localizedStringForKey:value:table:].



23
24
25
# File 'src/ruby/osx/objc/cocoa_macros.rb', line 23

def NSLocalizedStringFromTableInBundle (key, tbl, bundle, comment = nil)
  bundle.localizedStringForKey_value_table(key, "", tbl)
end

+ (Object) objc_class_method_add

Adds an Objective-C method by a given name.

Examples:

OSX.objc_class_method_add (AA::BB::CustomView, "drawRect:")

Parameters:

  • method_name (String)

    Method name

  • class_method (Boolean)

    Whether class method or not

  • types (String)

    Objective-C encoding types

Returns:

  • nil



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'src/objc/mdl_osxobjc.m', line 109

static VALUE
osx_mf_objc_class_method_add(VALUE mdl, VALUE kls, VALUE method_name, VALUE class_method, VALUE types)
{
  Class a_class;
  SEL a_sel;
  const char *kls_name;
  BOOL direct_override;

  method_name = rb_obj_as_string(method_name);
  a_sel = sel_registerName(StringValuePtr(method_name));
  if (a_sel == NULL)
    return Qnil;
  kls_name = rb_class2name(kls);
  if (strncmp(kls_name, "OSX::", 5) == 0 
      && (a_class = objc_lookUpClass(kls_name + 5)) != NULL 
      && !is_objc_derived_class(kls)) {
    // override in the current class
    direct_override = YES;
  }
  else {
    // override in the super class 
    a_class = RBObjcClassFromRubyClass(kls);
    direct_override = NO;
  }
  if (a_class != NULL) {
    id rcv;

    rcv = RTEST(class_method) ? a_class->isa : a_class;
    if (NIL_P(types))
      ovmix_register_ruby_method(rcv, a_sel, direct_override);
    else
      [rcv addRubyMethod:a_sel withType:StringValuePtr(types)];
  }
  return Qnil;
}

+ (Array?) objc_classnames

Returns an array of class names from Objective-C runtime. If a block is given, yields all Objective-C class names and returns nil.

Examples:

OSX.objc_classnames # => ["NSObject","NSArray", ..]

OSX.objc_classnames do |klassname|
  :
end

Returns:

Since:

  • 1.2.0



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'src/objc/mdl_osxobjc.m', line 176

static VALUE
osx_mf_objc_classnames(int argc, VALUE* argv, VALUE mdl)
{
  VALUE result;
  int num_klasses;
  int i;

  num_klasses = objc_getClassList(NULL, 0);
  result = rb_block_given_p() ? Qnil : rb_ary_new2(num_klasses);
  if (num_klasses > 0) {
    Class *klasses;

    klasses = malloc(sizeof(Class) * num_klasses);
    num_klasses = objc_getClassList(klasses, num_klasses);
    for (i = 0; i < num_klasses; i++) {
      Class klass = klasses[i];
      if (class_is_cocoa_class_p(klass)) {
        VALUE klass_name = rb_str_new2(strdup(class_getName(klass)));
        if (rb_block_given_p()) {
          rb_yield(klass_name);
        } else {
          rb_ary_push(result, klass_name);
        }
      }
    }
    free(klasses);
  }
  return result;
}

+ (Object) objc_derived_class_new

Defines new Objective-C subclass from Ruby class by a given name.

Examples:

declare new Objective-C class named “CustomView” as a subclass of “NSView”.

OSX.objc_derived_class_new (AA::BB::CustomView, "CustomView", "NSView")

Parameters:

  • kls (Class)

    Ruby class

  • kls_name (String)

    Objective-C class name

  • super_name (String)

    Objective-C superclass name

Returns:

  • nil



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'src/objc/mdl_osxobjc.m', line 82

static VALUE
osx_mf_objc_derived_class_new(VALUE mdl, VALUE kls, VALUE kls_name, VALUE super_name)
{
  Class super_class;
  Class new_cls = nil;

  kls_name = rb_obj_as_string(kls_name);
  super_name = rb_obj_as_string(super_name);
  super_class = objc_getClass(StringValuePtr(super_name));
  if (super_class)
    new_cls = RBObjcDerivedClassNew(kls, StringValuePtr(kls_name), super_class);

  if (new_cls)
    return ocobj_s_new(new_cls);
  return Qnil;
}

+ (Object) objc_proxy_class_new

Defines new Objective-C class from Ruby class by a given name.

Examples:

declare new Objective-C class named “AppController”.

OSX.objc_proxy_class_new (AA::BB::AppController, "AppController")

Parameters:

  • kls (Class)

    Ruby class

  • kls_name (String)

    Objective-C class name

Returns:

  • nil



65
66
67
68
69
70
71
# File 'src/objc/mdl_osxobjc.m', line 65

static VALUE
osx_mf_objc_proxy_class_new(VALUE mdl, VALUE kls, VALUE kls_name)
{
  kls_name = rb_obj_as_string(kls_name);
  RBObjcClassNew(kls, StringValuePtr(kls_name), [RBObject class]);
  return Qnil;
}

+ (String) object_to_plist(object, format = nil)

Serialize to property list.

Parameters:

  • object (String, OSX::NSString, OSX::NSData)
  • format (NSPropertyListFormat) (defaults to: nil)

Returns:



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'src/ruby/osx/objc/ruby_addition.rb', line 78

def object_to_plist(object, format=nil)
  format ||= OSX::NSPropertyListXMLFormat_v1_0
  data, error = OSX::NSPropertyListSerialization.objc_send \
    :dataFromPropertyList, object,
    :format, format,
    :errorDescription
  raise error.to_s if data.nil?
  case format
    when OSX::NSPropertyListXMLFormat_v1_0, 
         OSX::NSPropertyListOpenStepFormat
      OSX::NSString.alloc.initWithData_encoding(data, 
        OSX::NSUTF8StringEncoding).to_s
    else
      data.rubyString
  end
end

+ (Object) rbobj_to_nsobj

Converts Ruby objects to Objective-C objects.



453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'src/objc/mdl_osxobjc.m', line 453

static VALUE
osx_rbobj_to_nsobj (VALUE rcv, VALUE obj)
{
  id ocid, pool;
  VALUE val;

  pool = [[NSAutoreleasePool alloc] init];
  if (!rbobj_to_nsobj(obj, &ocid) || ocid == nil) {
    [pool release];
    return Qnil;
  }

  val = ocid_to_rbobj(Qnil, ocid);
  [ocid retain];
  OBJCID_DATA_PTR(val)->retained = YES;
  OBJCID_DATA_PTR(val)->can_be_released = YES;

  [pool release];

  return val;
}

+ (Object) require_framework(framework)

“require” for OSX .framework.

The OSX::require_framework method imports Mac OS X frameworks and uses the BridgeSupport metadata to add Ruby entry points for the framework's Classes, methods, and Constants into the OSX module.

The framework parameter is a reference to the framework that should be imported. This may be a full path name to a particular framework, a shortcut, or a framework name. The shortcuts are the keys listed in the QUICK_FRAMEWORKS hash.

If a framework name (with no path) is given, then the method searches a number of directories. Those directories (in search order) are:

  1. /System/Library/Frameworks

  2. /Library/Frameworks

  3. Any directories in the RUBYCOCOA_FRAMEWORK_PATHS array, if defined

  4. ENV/Library/Frameworks, if the HOME environment variable is defined

When using the search paths, the .framework file type extension should be omitted from the framework name passed to the method.

If the method loads the framework successfully, it returns true. If the framework was already loaded the method returns false. If the method is unable to locate, or unable to load the framework then it raises an ArgumentError.



97
98
99
100
101
102
103
104
105
106
107
# File 'src/ruby/osx/objc/oc_import.rb', line 97

def require_framework(framework)
  return false if framework_loaded?(framework)
  bundle, path = _bundle_path_for_framework(framework)
  bundle.oc_load
  if not bundle.isLoaded? then
    raise ArgumentError, "Can't load framework '#{framework}'" 
  end
  load_bridge_support_signatures(path)
  ns_import_all if RUBY_VERSION >= '2.0' # create ruby classes from Objective-C
  return true
end

+ (nil) ruby_thread_switcher_start

Start switching ruby thread at short interval (default: 5/1000 sec). RubyCocoa start switching at application launched.

Parameters:

  • interval (Float)

    switching interval seconds. (optional)

  • wait (Float)

    wait seconds when running thread is busy. (optional)

Returns:

  • (nil)


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'src/objc/mdl_osxobjc.m', line 213

static VALUE
osx_mf_ruby_thread_switcher_start(int argc, VALUE* argv, VALUE mdl)
{
  volatile VALUE arg_interval, arg_wait;
  double interval, wait;

  rb_scan_args(argc, argv, "02", &arg_interval, &arg_wait);

  if (arg_interval == Qnil) {
    [RBThreadSwitcher start];
  }
  else {
    Check_Type(arg_interval, T_FLOAT);
    interval = RFLOAT_VALUE(arg_interval);

    if (arg_wait == Qnil) {
      [RBThreadSwitcher start: interval];
    }
    else {
      Check_Type(arg_wait, T_FLOAT);
      wait = RFLOAT_VALUE(arg_wait);
      [RBThreadSwitcher start: interval wait: wait];
    }
  }
  return Qnil;
}

+ (nil) ruby_thread_switcher_stop

Stop switching ruby thread at short interval.

Returns:

  • (nil)


244
245
246
247
248
249
# File 'src/objc/mdl_osxobjc.m', line 244

static VALUE
osx_mf_ruby_thread_switcher_stop(VALUE mdl)
{
  [RBThreadSwitcher stop];
  return Qnil;
}