Declare works on simulator not device

Good morning.

I wrote some declares to make use of the iOS NSCalendar class. They work fine when I run on the simulator. They are not working when I run on a phone. There’s no crash, just no results.

Anyone have any suggestions?

-Bob

Could you post a bit of the code?

A bit of code:

#tag Class
Protected Class CalendarConverter
	#tag ExternalMethod, Flags = &h21
		Private Declare Function alloc Lib "Foundation" Selector "alloc" (id as Ptr) As Ptr
	#tag EndExternalMethod

	#tag Method, Flags = &h21
		Private Function components(pCalendar as Ptr, unitFlags as UInt64, pDate as Date) As Ptr
		  
		  dim result as Ptr
		  dim nDate  as Ptr
		  
		  
		  declare Function components _
		  lib "Foundation" _
		  selector "components:fromDate:" (calendar as Ptr, flags as Integer, fromDate as Ptr) as Ptr
		  
		  nDate  = self.NSDate(pDate)
		  result = components(pCalendar,unitFlags,nDate)
		  
		  return result
		  
		  
		End Function
	#tag EndMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Function dateFromComponents Lib "Foundation" Selector "dateFromComponents:" (pCalendar as Ptr, pComponents as Ptr) As Ptr
	#tag EndExternalMethod

	#tag Method, Flags = &h0
		Function GregorianToHebrew(pDate as Date) As Date
		  
		  
		  // see: http://stackoverflow.com/questions/4644451/gregorian-to-hebrew
		  // and: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtCalendars.html
		  // and: https://forum.xojo.com/23627-how-to-get-date/0
		  
		  dim g1 as Ptr
		  dim g2 as Ptr
		  dim h1 as Ptr
		  dim h2 as Ptr
		  dim dc as Ptr
		  dim hd as Ptr
		  dim s1 as Double
		  dim s0 as Double
		  dim result as Date
		  dim d1 as ptr
		  
		  d1 = self.NSDate(pDate)
		  s0 = pDate.SecondsFrom1970
		  s1 = timeIntervalSince1970(d1)
		  
		  g1 = NSClassFromString("NSCalendar")
		  g2 = initWithCalendarIdentifier(alloc(g1),"gregorian")
		  h1 = NSClassFromString("NSCalendar")
		  h2 = initWithCalendarIdentifier(alloc(h1),"hebrew")
		  
		  dc = self.components(h2,self.unitDate + self.unitTime,pDate)
		  
		  hd = dateFromComponents(g2,dc)
		  
		  s1 = timeIntervalSince1970(hd)
		  
		  result = new Date(s1,Timezone.Current)
		  return result
		  
		  
		  
		End Function
	#tag EndMethod

	#tag ExternalMethod, Flags = &h1, Description = 416C6C6F6361746573206D656D6F727920666F7220616E206F626A6563742E2043617374206F6E206120436C6173735074722E
		Protected Declare Function init Lib "Foundation" Selector "init" (id as ptr) As ptr
	#tag EndExternalMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Function initWithCalendarIdentifier Lib "Foundation" Selector "initWithCalendarIdentifier:" (id as Ptr, name as CFStringRef) As Ptr
	#tag EndExternalMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Function NSClassFromString Lib "foundation" (pClassName as CFStringRef) As Ptr
	#tag EndExternalMethod

	#tag Method, Flags = &h21
		Private Function NSDate(pDate as Date) As Ptr
		  /// class:       CalendarConverter
		  /// method:      NSDate
		  /// summary:     creates as NSDate from a Xojo date
		  /// parameters:  pDate as Date, the Xojo date to convert to an NSDate
		  /// returns:     Ptr, an NSDate
		  /// author:      Bob Gordon
		  /// date:        May 4, 2017
		  
		  dim datePtr as Ptr
		  
		  Dim NSDateClass as Ptr = NSClassFromString("NSDate")
		  Declare Function dateWithTimeIntervalSince1970 _
		  Lib "Foundation" Selector "dateWithTimeIntervalSince1970:" (classRef As Ptr, seconds As Double) As Ptr
		  
		  datePtr = dateWithTimeIntervalSince1970(NSDateClass,pDate.SecondsFrom1970)
		  
		  return datePtr
		  
		  
		End Function
	#tag EndMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Sub release Lib "Foundation" Selector "release" (id as ptr)
	#tag EndExternalMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Function timeIntervalSince1970 Lib "Foundation" Selector "timeIntervalSince1970" (pDate as Ptr) As Double
	#tag EndExternalMethod

	#tag ExternalMethod, Flags = &h21
		Private Declare Function timeIntervalSinceReferenceDate Lib "Foundation" Selector "timeIntervalSinceReferenceDate" (pDate as Ptr) As Double
	#tag EndExternalMethod


	#tag Property, Flags = &h21
		Private months() As Text
	#tag EndProperty


	#tag Constant, Name = NSUIntegerMax, Type = Double, Dynamic = False, Default = \"&hffffffffffffffff", Scope = Private
	#tag EndConstant

	#tag Constant, Name = StyleLong, Type = Double, Dynamic = False, Default = \"3", Scope = Private
	#tag EndConstant

	#tag Constant, Name = StyleMedium, Type = Double, Dynamic = False, Default = \"2", Scope = Private
	#tag EndConstant

	#tag Constant, Name = StyleNone, Type = Double, Dynamic = False, Default = \"0", Scope = Private
	#tag EndConstant

	#tag Constant, Name = StyleShort, Type = Double, Dynamic = False, Default = \"1", Scope = Private
	#tag EndConstant

	#tag Constant, Name = UnitDate, Type = Double, Dynamic = False, Default = \"28", Scope = Private
	#tag EndConstant

	#tag Constant, Name = UnitDay, Type = Double, Dynamic = False, Default = \"16", Scope = Private
	#tag EndConstant

	#tag Constant, Name = UnitMonth, Type = Double, Dynamic = False, Default = \"8", Scope = Private
	#tag EndConstant

	#tag Constant, Name = UnitTime, Type = Double, Dynamic = False, Default = \"224", Scope = Private
	#tag EndConstant

	#tag Constant, Name = UnitYear, Type = Double, Dynamic = False, Default = \"4", Scope = Private
	#tag EndConstant


	#tag ViewBehavior
		#tag ViewProperty
			Name="Index"
			Visible=true
			Group="ID"
			InitialValue="-2147483648"
			Type="Integer"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Left"
			Visible=true
			Group="Position"
			InitialValue="0"
			Type="Integer"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Name"
			Visible=true
			Group="ID"
			Type="String"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Super"
			Visible=true
			Group="ID"
			Type="String"
		#tag EndViewProperty
		#tag ViewProperty
			Name="Top"
			Visible=true
			Group="Position"
			InitialValue="0"
			Type="Integer"
		#tag EndViewProperty
	#tag EndViewBehavior
End Class
#tag EndClass

Phew, quite a lot! I will have to check that more thoroughly, but a first hint might be that dateWithTimeIntervalSince1970 is a class constructor which means the object created is not retained. This often works in certain constructions, but especially when returning the ptr to somewhere else the object might simply cease to exist.
As a first attempt I would propose to cast a retain on it once you have it created (and at the end release it).

Ulrich,

Thanks for the hint. This is actually just a part of the code. I was having trouble getting the entire class to post.

I would expect the simulator to work like the phone. That is, if it works in the simulator, it should work on the phone. Is this not true?

-Bob

Sadly no. The simulator is a simulator, not an emulator. It tries to mimic the device, but it is no perfect substitute for the real thing. Which is very disappointing with several graphics routines that, although existent on macOS too, are only rendered on the CPU which makes the simulator extremely slow. Timing in general is nothing one can depend on.

Ulrich,

I tracked down the problem to the NSCalendar component:fromDate: method. Don’t know why, but it is giving a seriously wrong result but only on the phone.

I changed what I was doing to use the NSDateFormatter class. Everything seems to be working correctly now (pending further testing, of course). Thank you for your assistance.

-Bob

I’m not sure if this is the entire cause, but the declare is incorrect. NSCalendarUnit is a typedef for NSUInteger, so the Xojo declare should have flags as UInteger instead of Integer.

@Joe Ranieri do you have some documentation on why Integer vs. UInteger should make a difference?