Class: Idevice::MobileSyncClient

Inherits:
C::ManagedOpaquePointer show all
Includes:
LibHelpers
Defined in:
lib/idevice/mobilesync.rb

Overview

Used to synchronize data classes with a device and computer.

Constant Summary collapse

SYNC_TYPES =
[
  :FAST,  # Fast-sync requires that only the changes made since the last synchronization should be reported by the computer.
  :SLOW,  # Slow-sync requires that all data from the computer needs to be synchronized/sent.
  :RESET, # Reset-sync signals that the computer should send all data again.
]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LibHelpers

included

Methods inherited from C::ManagedOpaquePointer

#initialize

Constructor Details

This class inherits a constructor from Idevice::C::ManagedOpaquePointer

Class Method Details

.attach(opts = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/idevice/mobilesync.rb', line 43

def self.attach(opts={})
    _attach_helper("com.apple.mobilesync", opts) do |idevice, ldsvc, p_ms|
    err = C.mobilesync_client_new(idevice, ldsvc, p_ms)
    raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

    ms = p_ms.read_pointer
    raise MobileSyncError, "mobilesync_client_new returned a NULL client" if ms.null?
    return new(ms)
  end
end

.release(ptr) ⇒ Object



35
36
37
38
39
40
41
# File 'lib/idevice/mobilesync.rb', line 35

def self.release(ptr)
  C::Freelock.synchronize do
    unless ptr.null?
      C.mobilesync_client_free(ptr)
    end
  end
end

Instance Method Details

#_send_changes(entities, is_last, actions = nil) ⇒ Object

Raises:



181
182
183
184
185
# File 'lib/idevice/mobilesync.rb', line 181

def _send_changes(entities, is_last, actions=nil)
  act = actions ? Plist_t.from_ruby(actions) : nil
  err = C.mobilesync_send_changes(self, Plist_t.from_ruby(entities), is_last, act)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
end

#acknowledge_changes_from_deviceObject

Raises:



167
168
169
170
171
172
# File 'lib/idevice/mobilesync.rb', line 167

def acknowledge_changes_from_device
  err = C.mobilesync_acknowledge_changes_from_device(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#cancel(reason) ⇒ Object

Raises:



108
109
110
111
112
113
# File 'lib/idevice/mobilesync.rb', line 108

def cancel(reason)
  err = C.mobilesync_cancel(self, reason)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#clear_all_records_on_deviceObject

Raises:



136
137
138
139
140
141
# File 'lib/idevice/mobilesync.rb', line 136

def clear_all_records_on_device
  err = C.mobilesync_clear_all_records_on_device(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#finishObject

Raises:



115
116
117
118
119
120
# File 'lib/idevice/mobilesync.rb', line 115

def finish
  err = C.mobilesync_finish(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#receive_changesObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/idevice/mobilesync.rb', line 143

def receive_changes
  ret = []

  FFI::MemoryPointer.new(:pointer) do |p_entities|
    FFI::MemoryPointer.new(:uint8) do |p_is_last_record|
      FFI::MemoryPointer.new(:pointer) do |p_actions|
        last_record = false
        until last_record
          err = C.mobilesync_receive_changes(self, p_entities, p_is_last_record, p_actions)
          raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

          last_record = (p_is_last_record.read_uint8 != 0)
          ret << {
            entities: p_entities.read_pointer.read_plist_t,
            actions:  p_actions.read_pointer.read_plist_t,
          }
        end
      end
    end
  end

  return ret
end

#receive_plistObject



54
55
56
57
58
59
60
# File 'lib/idevice/mobilesync.rb', line 54

def receive_plist
  FFI::MemoryPointer.new(:pointer) do |p_result|
    err = C.mobilesync_receive(self, p_result)
    raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
    return p_result.read_pointer.read_plist_t
  end
end

#remap_identifiers(mappings) ⇒ Object

mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping);

Raises:

  • (TypeError)


198
199
200
201
202
203
204
205
206
207
208
# File 'lib/idevice/mobilesync.rb', line 198

def remap_identifiers(mappings)
  raise TypeError, "mappings must be an array" unless changes.is_a? Array
  raise ArgumentError, "mappings must not be empty" if changes.empty?

  FFI::MemoryPointer.new(FFI::Pointer.size * (mappings.count+1)) do |p_mapping|
    p_mapping.write_array_of_pointer(mappings.map{|m| Plist_t.from_ruby(m)} + nil)
    err = C.mobilesync_remap_identifiers(self, p_mapping)
    raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS
    return true
  end
end

#request_all_records_from_deviceObject

Raises:



122
123
124
125
126
127
# File 'lib/idevice/mobilesync.rb', line 122

def request_all_records_from_device
  err = C.mobilesync_get_all_records_from_device(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#request_changes_from_deviceObject

Raises:



129
130
131
132
133
134
# File 'lib/idevice/mobilesync.rb', line 129

def request_changes_from_device
  err = C.mobilesync_get_changes_from_device(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#send_changes(changes) ⇒ Object

Raises:

  • (TypeError)


187
188
189
190
191
192
193
194
195
# File 'lib/idevice/mobilesync.rb', line 187

def send_changes(changes)
  raise TypeError, "changes must be an array" unless changes.is_a? Array
  raise ArgumentError, "changes must not be empty" if changes.empty?

  lastchange = changes.unshift
  changes.each { |change| _send_changes(change[:entities], 0, change[:actions]) }
  _send_changes(lastchange[:entities], 1, lastchange[:actions])
  return true
end

#send_plist(request) ⇒ Object

Raises:



62
63
64
65
66
67
# File 'lib/idevice/mobilesync.rb', line 62

def send_plist(request)
  err = C.mobilesync_send(self, Plist_t.from_ruby(request))
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#signal_ready_to_send_changes_from_computerObject

Raises:



174
175
176
177
178
179
# File 'lib/idevice/mobilesync.rb', line 174

def signal_ready_to_send_changes_from_computer
  err = C.mobilesync_ready_to_send_changes_from_computer(self)
  raise MobileSyncError, "MobileSync error: #{err}" if err != :SUCCESS

  return true
end

#start(data_class, anchors, data_class_version = 106) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/idevice/mobilesync.rb', line 75

def start(data_class, anchors, data_class_version=106)
  anchors = C.mobilesync_anchors_new(*anchors)

  FFI::MemoryPointer.new(:int) do |p_sync_type|
    FFI::MemoryPointer.new(:uint64) do |p_dev_data_class_version|
      FFI::MemoryPointer.new(:pointer) do |p_error|
        err = C.mobilesync_send(self, data_class, anchors, data_class_version, p_sync_type, p_dev_data_class_version, p_error)
        errstr = nil
        p_errstr = p_error.read_pointer
        unless p_errstr.null?
          errstr = p_errstr.read_string
          C.free(p_errstr)
        end

        if err != :SUCCESS
          msg = "MobileSync error: #{err}"
          msg << "(#{errstr})" if errstr
          raise MobileSyncError, msg
        end

        sync_type = sync_type.read_int
        ddc_ver = p_device_data_class_version.read_uint64

        return({
          sync_type: (SYNC_TYPES[sync_type] || sync_type),
          device_data_class_version: ddc_ver,
          error: errstr,
        })
      end
    end
  end
end