@@ -214,6 +214,76 @@ [new NSSortDescriptor(HKSample.SortIdentifierStartDate, false)],
214214 }
215215 }
216216
217+ //https://github.com/Kebechet/Maui.Health/pull/8/files
218+ //Split to `public partial` and `private async` method because of trimmer/linker issue
219+ public partial Task < bool > WriteHealthData < TDto > ( TDto data , CancellationToken cancellationToken )
220+ where TDto : HealthMetricBase
221+ {
222+ return WriteHealthDataInternal ( data , cancellationToken ) ;
223+ }
224+
225+ private async Task < bool > WriteHealthDataInternal < TDto > ( TDto data , CancellationToken cancellationToken )
226+ where TDto : HealthMetricBase
227+ {
228+ if ( ! IsSupported )
229+ {
230+ return false ;
231+ }
232+
233+ try
234+ {
235+ _logger . LogInformation ( "iOS WriteHealthDataAsync<{DtoName}>" , typeof ( TDto ) . Name ) ;
236+
237+ // Request write permission for the specific metric
238+ var readPermission = MetricDtoExtensions . GetRequiredPermission < TDto > ( ) ;
239+ var writePermission = new HealthPermissionDto
240+ {
241+ HealthDataType = readPermission . HealthDataType ,
242+ PermissionType = PermissionType . Write
243+ } ;
244+ var permissionResult = await RequestPermissions ( [ writePermission ] , cancellationToken : cancellationToken ) ;
245+ if ( ! permissionResult . IsSuccess )
246+ {
247+ _logger . LogWarning ( "iOS Write: Permission denied for {DtoName}" , typeof ( TDto ) . Name ) ;
248+ return false ;
249+ }
250+
251+ // Convert DTO to HKObject (HKQuantitySample or HKWorkout)
252+ HKObject ? sample = data . ToHKObject ( ) ;
253+ if ( sample == null )
254+ {
255+ _logger . LogWarning ( "iOS Write: Failed to convert {DtoName} to HKObject" , typeof ( TDto ) . Name ) ;
256+ return false ;
257+ }
258+
259+ // Save to HealthKit
260+ using var healthStore = new HKHealthStore ( ) ;
261+ var tcs = new TaskCompletionSource < bool > ( ) ;
262+
263+ healthStore . SaveObject ( sample , ( success , error ) =>
264+ {
265+ if ( error != null )
266+ {
267+ _logger . LogError ( "iOS Write Error: {Error}" , error . LocalizedDescription ) ;
268+ tcs . TrySetResult ( false ) ;
269+ }
270+ else
271+ {
272+ _logger . LogInformation ( "iOS Write: Successfully wrote {DtoName}" , typeof ( TDto ) . Name ) ;
273+ tcs . TrySetResult ( success ) ;
274+ }
275+ } ) ;
276+
277+ using var ct = cancellationToken . Register ( ( ) => tcs . TrySetCanceled ( ) ) ;
278+ return await tcs . Task ;
279+ }
280+ catch ( Exception ex )
281+ {
282+ _logger . LogError ( ex , "iOS Write Exception for {DtoName}" , typeof ( TDto ) . Name ) ;
283+ return false ;
284+ }
285+ }
286+
217287 private static bool IsCumulativeType < TDto > ( ) where TDto : HealthMetricBase
218288 {
219289 return typeof ( TDto ) == typeof ( StepsDto ) ||
@@ -225,7 +295,8 @@ private async Task<List<TDto>> GetCumulativeHealthDataAsync<TDto>(
225295 NSPredicate predicate ,
226296 HealthTimeRange timeRange ,
227297 HealthDataType healthDataType ,
228- CancellationToken cancellationToken ) where TDto : HealthMetricBase
298+ CancellationToken cancellationToken )
299+ where TDto : HealthMetricBase
229300 {
230301 var tcs = new TaskCompletionSource < TDto [ ] > ( ) ;
231302
@@ -299,66 +370,4 @@ private async Task<List<TDto>> GetCumulativeHealthDataAsync<TDto>(
299370
300371 return results . ToList ( ) ;
301372 }
302-
303- public async partial Task < bool > WriteHealthData < TDto > ( TDto data , CancellationToken cancellationToken ) where TDto : HealthMetricBase
304- {
305- if ( ! IsSupported )
306- {
307- return false ;
308- }
309-
310- try
311- {
312- _logger . LogInformation ( "iOS WriteHealthDataAsync<{DtoName}>" , typeof ( TDto ) . Name ) ;
313-
314- // Request write permission for the specific metric
315- var readPermission = MetricDtoExtensions . GetRequiredPermission < TDto > ( ) ;
316- var writePermission = new HealthPermissionDto
317- {
318- HealthDataType = readPermission . HealthDataType ,
319- PermissionType = PermissionType . Write
320- } ;
321- var permissionResult = await RequestPermissions ( [ writePermission ] , cancellationToken : cancellationToken ) ;
322- if ( ! permissionResult . IsSuccess )
323- {
324- _logger . LogWarning ( "iOS Write: Permission denied for {DtoName}" , typeof ( TDto ) . Name ) ;
325- return false ;
326- }
327-
328- // Convert DTO to HKObject (HKQuantitySample or HKWorkout)
329- HKObject ? sample = data . ToHKObject ( ) ;
330- if ( sample == null )
331- {
332- _logger . LogWarning ( "iOS Write: Failed to convert {DtoName} to HKObject" , typeof ( TDto ) . Name ) ;
333- return false ;
334- }
335-
336- // Save to HealthKit
337- using var healthStore = new HKHealthStore ( ) ;
338- var tcs = new TaskCompletionSource < bool > ( ) ;
339-
340- healthStore . SaveObject ( sample , ( success , error ) =>
341- {
342- if ( error != null )
343- {
344- _logger . LogError ( "iOS Write Error: {Error}" , error . LocalizedDescription ) ;
345- tcs . TrySetResult ( false ) ;
346- }
347- else
348- {
349- _logger . LogInformation ( "iOS Write: Successfully wrote {DtoName}" , typeof ( TDto ) . Name ) ;
350- tcs . TrySetResult ( success ) ;
351- }
352- } ) ;
353-
354- using var ct = cancellationToken . Register ( ( ) => tcs . TrySetCanceled ( ) ) ;
355- return await tcs . Task ;
356- }
357- catch ( Exception ex )
358- {
359- _logger . LogError ( ex , "iOS Write Exception for {DtoName}" , typeof ( TDto ) . Name ) ;
360- return false ;
361- }
362- }
363-
364373}
0 commit comments