diff --git a/Framework/MIKMIDI.xcodeproj/project.pbxproj b/Framework/MIKMIDI.xcodeproj/project.pbxproj index 134c39bc..b78977c8 100644 --- a/Framework/MIKMIDI.xcodeproj/project.pbxproj +++ b/Framework/MIKMIDI.xcodeproj/project.pbxproj @@ -255,6 +255,8 @@ 9DB366F71A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DB366F41A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DB366F81A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DB366F51A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.m */; }; 9DB366F91A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DB366F51A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.m */; }; + 9DB8CD421BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DB8CD401BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h */; }; + 9DB8CD431BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 9DB8CD401BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h */; }; 9DBEBD581AAA21BE00E59734 /* MIKMIDICommand_SubclassMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D74EF3517A713A100BEE89F /* MIKMIDICommand_SubclassMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DBEBD591AAA21BE00E59734 /* MIKMIDICommand_SubclassMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D74EF3517A713A100BEE89F /* MIKMIDICommand_SubclassMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9DBEBD5A1AAA21C400E59734 /* MIKMIDIEvent_SubclassMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 839D932D19C3A2C9007589C3 /* MIKMIDIEvent_SubclassMethods.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -446,6 +448,7 @@ 9DB366EF1A964C55001D1CF3 /* MIKMIDISynthesizer.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = MIKMIDISynthesizer.m; sourceTree = ""; tabWidth = 4; usesTabs = 1; wrapsLines = 1; }; 9DB366F41A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIKMIDISynthesizerInstrument.h; sourceTree = ""; }; 9DB366F51A964D4A001D1CF3 /* MIKMIDISynthesizerInstrument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIKMIDISynthesizerInstrument.m; sourceTree = ""; }; + 9DB8CD401BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIKMIDIMetaEvent_SubclassMethods.h; sourceTree = ""; }; 9DBEBD5C1AAA27D100E59734 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = SOURCE_ROOT; }; 9DBEBD651AAA303700E59734 /* MIKMIDIChannelPressureEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIKMIDIChannelPressureEvent.h; sourceTree = ""; }; 9DBEBD661AAA303700E59734 /* MIKMIDIChannelPressureEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIKMIDIChannelPressureEvent.m; sourceTree = ""; }; @@ -700,6 +703,7 @@ isa = PBXGroup; children = ( 839D933B19C3A2F5007589C3 /* MIKMIDIMetaEvent.h */, + 9DB8CD401BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h */, 839D933C19C3A2F5007589C3 /* MIKMIDIMetaEvent.m */, 839D933719C3A2F5007589C3 /* MIKMIDIMetaCopyrightEvent.h */, 839D933819C3A2F5007589C3 /* MIKMIDIMetaCopyrightEvent.m */, @@ -861,6 +865,7 @@ 9D74EF7117A713A100BEE89F /* MIKMIDIEndpoint.h in Headers */, 83FB360E1B42D58000F91DCD /* MIKMIDISequence+MIKMIDIPrivate.h in Headers */, 9D74EF7317A713A100BEE89F /* MIKMIDIEntity.h in Headers */, + 9DB8CD421BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h in Headers */, 9D74EF7517A713A100BEE89F /* MIKMIDIErrors.h in Headers */, 9D74EF7717A713A100BEE89F /* MIKMIDIInputPort.h in Headers */, 9D74EF7917A713A100BEE89F /* MIKMIDIMapping.h in Headers */, @@ -948,6 +953,7 @@ 9DAF8B631A7B008A00F46528 /* MIKMIDINoteOnCommand.h in Headers */, 9D84951D1AA7678700C52475 /* MIKMIDIProgramChangeEvent.h in Headers */, 9DAF8B5E1A7B007300F46528 /* MIKMIDIDestinationEndpoint.h in Headers */, + 9DB8CD431BF266FE00F6388D /* MIKMIDIMetaEvent_SubclassMethods.h in Headers */, 9D3781561AA407A7007A61BE /* MIKMIDIResponder.h in Headers */, 9DAF8B7B1A7B00A700F46528 /* MIKMIDIPlayer.h in Headers */, 9DAF8B781A7B00A700F46528 /* MIKMIDIMetaTimeSignatureEvent.h in Headers */, diff --git a/Source/MIKMIDIChannelEvent.h b/Source/MIKMIDIChannelEvent.h index 11ed8858..78f313d9 100644 --- a/Source/MIKMIDIChannelEvent.h +++ b/Source/MIKMIDIChannelEvent.h @@ -7,6 +7,9 @@ // #import +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDIChannelEvent : MIKMIDIEvent @@ -18,7 +21,7 @@ * * @return A new instance of a subclass of MIKMIDIChannelEvent, or nil if there is an error. */ -+ (instancetype)channelEventWithTimeStamp:(MusicTimeStamp)timeStamp message:(MIDIChannelMessage)message; ++ (nullable instancetype)channelEventWithTimeStamp:(MusicTimeStamp)timeStamp message:(MIDIChannelMessage)message; // Properties @@ -45,21 +48,27 @@ @interface MIKMutableMIDIChannelEvent : MIKMIDIChannelEvent @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; @end +NS_ASSUME_NONNULL_END + #pragma mark - #import @class MIKMIDIClock; +NS_ASSUME_NONNULL_BEGIN + @interface MIKMIDICommand (MIKMIDIChannelEventToCommands) -+ (instancetype)commandFromChannelEvent:(MIKMIDIChannelEvent *)event clock:(MIKMIDIClock *)clock; ++ (nullable instancetype)commandFromChannelEvent:(MIKMIDIChannelEvent *)event clock:(MIKMIDIClock *)clock; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIChannelPressureEvent.h b/Source/MIKMIDIChannelPressureEvent.h index be1dc309..27ba7afd 100644 --- a/Source/MIKMIDIChannelPressureEvent.h +++ b/Source/MIKMIDIChannelPressureEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A channel pressure (aftertouch) event. @@ -32,9 +35,11 @@ @property (nonatomic, readwrite) UInt8 pressure; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIChannelVoiceCommand.h b/Source/MIKMIDIChannelVoiceCommand.h index 72030f16..93e606d6 100644 --- a/Source/MIKMIDIChannelVoiceCommand.h +++ b/Source/MIKMIDIChannelVoiceCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDICommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDIChannelVoiceCommand is used to represent MIDI messages whose type is @@ -46,6 +49,8 @@ @property (nonatomic, readwrite) UInt8 dataByte2; @property (nonatomic, readwrite) MIDITimeStamp midiTimestamp; -@property (nonatomic, copy, readwrite) NSData *data; +@property (nonatomic, copy, readwrite, null_resettable) NSData *data; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIChannelVoiceCommand_SubclassMethods.h b/Source/MIKMIDIChannelVoiceCommand_SubclassMethods.h index 1c680abc..7806d69f 100644 --- a/Source/MIKMIDIChannelVoiceCommand_SubclassMethods.h +++ b/Source/MIKMIDIChannelVoiceCommand_SubclassMethods.h @@ -8,9 +8,14 @@ #import "MIKMIDIChannelVoiceCommand.h" #import "MIKMIDICommand_SubclassMethods.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDIChannelVoiceCommand () @property (nonatomic, readwrite) NSUInteger value; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIClientDestinationEndpoint.h b/Source/MIKMIDIClientDestinationEndpoint.h index 7559b9a8..66f70397 100644 --- a/Source/MIKMIDIClientDestinationEndpoint.h +++ b/Source/MIKMIDIClientDestinationEndpoint.h @@ -7,9 +7,12 @@ // #import "MIKMIDIDestinationEndpoint.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIClientDestinationEndpoint; +NS_ASSUME_NONNULL_BEGIN + typedef void(^MIKMIDIClientDestinationEndpointEventHandler)(MIKMIDIClientDestinationEndpoint *destination, NSArray *commands); /** @@ -37,11 +40,13 @@ typedef void(^MIKMIDIClientDestinationEndpointEventHandler)(MIKMIDIClientDestina * * @return An instance of MIKMIDIClientDestinationEndpoint, or nil if an error occurs. */ -- (instancetype)initWithName:(NSString *)name receivedMessagesHandler:(MIKMIDIClientDestinationEndpointEventHandler)handler; +- (nullable instancetype)initWithName:(NSString *)name receivedMessagesHandler:(nullable MIKMIDIClientDestinationEndpointEventHandler)handler; /** * A block to be called when the receiver receives new incoming MIDI messages. */ -@property (nonatomic, strong) MIKMIDIClientDestinationEndpointEventHandler receivedMessagesHandler; +@property (nonatomic, strong, nullable) MIKMIDIClientDestinationEndpointEventHandler receivedMessagesHandler; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIClientSourceEndpoint.h b/Source/MIKMIDIClientSourceEndpoint.h index 887be9a3..c4411947 100644 --- a/Source/MIKMIDIClientSourceEndpoint.h +++ b/Source/MIKMIDIClientSourceEndpoint.h @@ -6,6 +6,9 @@ // #import "MIKMIDISourceEndpoint.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDIClientSourceEndpoint represents a virtual endpoint created by your application to send MIDI @@ -27,7 +30,7 @@ * * @return An instance of MIKMIDIClientSourceEndpoint, or nil if an error occurs. */ -- (instancetype)initWithName:(NSString*)name; +- (nullable instancetype)initWithName:(NSString *)name; /** * Used to send MIDI messages/commands from your application to a MIDI output endpoint. @@ -41,3 +44,5 @@ - (BOOL)sendCommands:(NSArray *)commands error:(NSError **)error; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIClock.h b/Source/MIKMIDIClock.h index 68966534..13a0e0fa 100644 --- a/Source/MIKMIDIClock.h +++ b/Source/MIKMIDIClock.h @@ -8,6 +8,7 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" /** * Returns the number of MIDITimeStamps that would occur during a specified time interval. @@ -25,6 +26,7 @@ Float64 MIKMIDIClockMIDITimeStampsPerTimeInterval(NSTimeInterval timeInterval); */ Float64 MIKMIDIClockSecondsPerMIDITimeStamp(); +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDIClock provides the number of seconds per MIDITimeStamp, as well as the @@ -213,6 +215,6 @@ Float64 MIKMIDIClockSecondsPerMIDITimeStamp(); */ + (Float64)midiTimeStampsPerTimeInterval:(NSTimeInterval)timeInterval DEPRECATED_ATTRIBUTE; - @end +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDICommand.h b/Source/MIKMIDICommand.h index 3bea78d9..9799b179 100644 --- a/Source/MIKMIDICommand.h +++ b/Source/MIKMIDICommand.h @@ -8,6 +8,7 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" /** * Types of MIDI messages. These values correspond directly to the MIDI command type values @@ -56,6 +57,8 @@ typedef NS_ENUM(NSUInteger, MIKMIDICommandType) { @class MIKMIDIMappingItem; +NS_ASSUME_NONNULL_BEGIN + /** * In MIKMIDI, MIDI messages are objects. Specifically, they are instances of MIKMIDICommand or one of its * subclasses. MIKMIDICommand's subclasses each represent a specific type of MIDI message, for example, @@ -193,14 +196,14 @@ typedef NS_ENUM(NSUInteger, MIKMIDICommandType) { /** * The raw data that makes up the receiver. */ -@property (nonatomic, copy, readonly) NSData *data; +@property (nonatomic, copy, readonly, null_resettable) NSData *data; /** * Optional mapping item used to route the command. This must be set by client code that handles * receiving MIDI commands. Allows responders to understand how a command was mapped, especially * useful to determine interaction type so that responders can interpret the command correctly. */ -@property (nonatomic, strong) MIKMIDIMappingItem *mappingItem; +@property (nonatomic, strong, nullable) MIKMIDIMappingItem *mappingItem; @end @@ -225,11 +228,12 @@ typedef NS_ENUM(NSUInteger, MIKMIDICommandType) { * transfered to the caller which becomes responsible for freeing the allocated memory. * Used by MIKMIDI when sending commands. Typically, this is not needed by clients of MIKMIDI. * - * @param outPacketList A pointer pointer to a MIDIPacketList structure which will point to the created MIDIPacketList + * @param outPacketList A pointer to a pointer to a MIDIPacketList structure which will point to the created MIDIPacketList * upon success. * @param commands An array of MIKMIDICommand instances. * * @return YES if creating the packet list was successful, NO if an error occurred. */ -BOOL MIKCreateMIDIPacketListFromCommands(MIDIPacketList **outPacketList, NSArray *commands); +BOOL MIKCreateMIDIPacketListFromCommands(MIDIPacketList * _Nonnull * _Nonnull outPacketList, NSArray *commands); +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDICommand.m b/Source/MIKMIDICommand.m index 6aed4ada..0969b510 100644 --- a/Source/MIKMIDICommand.m +++ b/Source/MIKMIDICommand.m @@ -298,7 +298,7 @@ - (void)setData:(NSData *)data { if (![[self class] isMutable]) return MIKMIDI_RAISE_MUTATION_ATTEMPT_EXCEPTION; - self.internalData = [data mutableCopy]; + self.internalData = data ? [data mutableCopy] : [NSMutableData data]; } @end diff --git a/Source/MIKMIDICommandScheduler.h b/Source/MIKMIDICommandScheduler.h index abfd4e56..496ac728 100644 --- a/Source/MIKMIDICommandScheduler.h +++ b/Source/MIKMIDICommandScheduler.h @@ -7,7 +7,9 @@ // #import +#import "MIKMIDICompilerCompatibility.h" +NS_ASSUME_NONNULL_BEGIN /** * Objects that conform to this protocol can be used as a destination for MIDI commands to @@ -20,3 +22,5 @@ - (void)scheduleMIDICommands:(NSArray *)commands; @end + +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDICommandThrottler.h b/Source/MIKMIDICommandThrottler.h index 380976c1..bcf45673 100644 --- a/Source/MIKMIDICommandThrottler.h +++ b/Source/MIKMIDICommandThrottler.h @@ -7,14 +7,16 @@ // #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIChannelVoiceCommand; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDICommandThrottler is a simple utility class useful for throttling e.g. jog wheel/turntable controls, * which otherwise send many messages per revolution. */ - @interface MIKMIDICommandThrottler : NSObject /** @@ -35,3 +37,5 @@ - (void)resetThrottlingCountForCommand:(MIKMIDIChannelVoiceCommand *)command; @end + +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDIControlChangeCommand.h b/Source/MIKMIDIControlChangeCommand.h index 5f094e9f..d1b0f6b9 100644 --- a/Source/MIKMIDIControlChangeCommand.h +++ b/Source/MIKMIDIControlChangeCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelVoiceCommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI control change message. @@ -33,7 +36,7 @@ * @return A new, single MIKMIDIControlChangeCommand instance containing 14-bit value data, and whose * fourteenBitCommand property is set to YES. */ -+ (instancetype)commandByCoalescingMSBCommand:(MIKMIDIControlChangeCommand *)msbCommand andLSBCommand:(MIKMIDIControlChangeCommand *)lsbCommand; ++ (nullable instancetype)commandByCoalescingMSBCommand:(MIKMIDIControlChangeCommand *)msbCommand andLSBCommand:(MIKMIDIControlChangeCommand *)lsbCommand; /** * The MIDI control number for the command. @@ -101,6 +104,8 @@ @property (nonatomic, readwrite) UInt8 dataByte2; @property (nonatomic, readwrite) MIDITimeStamp midiTimestamp; -@property (nonatomic, copy, readwrite) NSData *data; +@property (nonatomic, copy, readwrite, null_resettable) NSData *data; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIControlChangeEvent.h b/Source/MIKMIDIControlChangeEvent.h index 0f5b1cbe..30bd79f1 100644 --- a/Source/MIKMIDIControlChangeEvent.h +++ b/Source/MIKMIDIControlChangeEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * Control change events are typically sent when a controller value changes. @@ -40,9 +43,11 @@ @property (nonatomic, readwrite) NSUInteger controllerValue; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIDestinationEndpoint.h b/Source/MIKMIDIDestinationEndpoint.h index 31ed3de3..77993f56 100644 --- a/Source/MIKMIDIDestinationEndpoint.h +++ b/Source/MIKMIDIDestinationEndpoint.h @@ -8,6 +8,9 @@ #import "MIKMIDIEndpoint.h" #import "MIKMIDICommandScheduler.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDIDestinationEndpoint represents a source (input) MIDI endpoint. @@ -36,3 +39,5 @@ - (void)unscheduleAllPendingEvents; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIEndpoint.h b/Source/MIKMIDIEndpoint.h index b32d98a9..4faccd49 100644 --- a/Source/MIKMIDIEndpoint.h +++ b/Source/MIKMIDIEndpoint.h @@ -7,9 +7,12 @@ // #import "MIKMIDIObject.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIEntity; +NS_ASSUME_NONNULL_BEGIN + /** * Base class for MIDI endpoint objects. Not used directly, rather, in use, instances will always be * instances of MIKMIDISourceEndpoint or MIKMIDIDestinationEndpoint. @@ -19,7 +22,7 @@ /** * The entity that contains the receiver. Will be nil for non-wrapped virtual endpoints. */ -@property (nonatomic, weak, readonly) MIKMIDIEntity *entity; +@property (nonatomic, weak, readonly, nullable) MIKMIDIEntity *entity; /** * Whether or not the endpoint is private or hidden. See kMIDIPropertyPrivate in MIDIServices.h. @@ -27,3 +30,5 @@ @property (nonatomic, readonly) BOOL isPrivate; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIEndpointSynthesizer.h b/Source/MIKMIDIEndpointSynthesizer.h index 9f84ffca..d59dd097 100644 --- a/Source/MIKMIDIEndpointSynthesizer.h +++ b/Source/MIKMIDIEndpointSynthesizer.h @@ -7,12 +7,15 @@ // #import "MIKMIDISynthesizer.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIEndpoint; @class MIKMIDISourceEndpoint; @class MIKMIDIClientDestinationEndpoint; @class MIKMIDISynthesizerInstrument; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIEndpointSynthesizer is a subclass of MIKMIDISynthesizer that * provides a very simple way to synthesize MIDI commands coming from a @@ -33,7 +36,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -+ (instancetype)playerWithMIDISource:(MIKMIDISourceEndpoint *)source; ++ (nullable instancetype)playerWithMIDISource:(MIKMIDISourceEndpoint *)source; /** * Creates and initializes an MIKMIDIEndpointSynthesizer instance. @@ -44,7 +47,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -+ (instancetype)playerWithMIDISource:(MIKMIDISourceEndpoint *)source componentDescription:(AudioComponentDescription)componentDescription; ++ (nullable instancetype)playerWithMIDISource:(MIKMIDISourceEndpoint *)source componentDescription:(AudioComponentDescription)componentDescription; /** * Initializes an MIKMIDIEndpointSynthesizer instance using Apple's DLS synth as the @@ -54,7 +57,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)initWithMIDISource:(MIKMIDISourceEndpoint *)source; +- (nullable instancetype)initWithMIDISource:(MIKMIDISourceEndpoint *)source; /** * Initializes an MIKMIDIEndpointSynthesizer instance. @@ -65,7 +68,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)initWithMIDISource:(MIKMIDISourceEndpoint *)source componentDescription:(AudioComponentDescription)componentDescription; +- (nullable instancetype)initWithMIDISource:(MIKMIDISourceEndpoint *)source componentDescription:(AudioComponentDescription)componentDescription; /** * Creates and initializes an MIKMIDIEndpointSynthesizer instance using Apple's DLS synth as the @@ -75,7 +78,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -+ (instancetype)synthesizerWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination; ++ (nullable instancetype)synthesizerWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination; /** * Creates and initializes an MIKMIDIEndpointSynthesizer instance. @@ -86,7 +89,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -+ (instancetype)synthesizerWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination componentDescription:(AudioComponentDescription)componentDescription; ++ (nullable instancetype)synthesizerWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination componentDescription:(AudioComponentDescription)componentDescription; /** * Initializes an MIKMIDIEndpointSynthesizer instance using Apple's DLS synth as the @@ -96,7 +99,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)initWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination; +- (nullable instancetype)initWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination; /** * Initializes an MIKMIDIEndpointSynthesizer instance. @@ -107,7 +110,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)initWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination componentDescription:(AudioComponentDescription)componentDescription; +- (nullable instancetype)initWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpoint *)destination componentDescription:(AudioComponentDescription)componentDescription; // Properties @@ -117,7 +120,8 @@ * events coming from an external MIDI keyboard, or it may be an MIKMIDIClientDestinationEndpoint, * e.g. to synthesize MIDI events coming from an another application on the system. */ -@property (nonatomic, strong, readonly) MIKMIDIEndpoint *endpoint; +@property (nonatomic, strong, readonly, nullable) MIKMIDIEndpoint *endpoint; @end +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDIEndpointSynthesizer.m b/Source/MIKMIDIEndpointSynthesizer.m index 098f6de1..4cbf91c7 100644 --- a/Source/MIKMIDIEndpointSynthesizer.m +++ b/Source/MIKMIDIEndpointSynthesizer.m @@ -93,12 +93,10 @@ - (instancetype)initWithClientDestinationEndpoint:(MIKMIDIClientDestinationEndpo - (void)dealloc { - if (_endpoint) { - if ([_endpoint isKindOfClass:[MIKMIDISourceEndpoint class]]) { - [[MIKMIDIDeviceManager sharedDeviceManager] disconnectConnectionforToken:self.connectionToken]; - } - // Don't need to do anything for a destination endpoint. __weak reference in the messages handler will automatically nil out. + if ([_endpoint isKindOfClass:[MIKMIDISourceEndpoint class]]) { + [[MIKMIDIDeviceManager sharedDeviceManager] disconnectConnectionforToken:self.connectionToken]; } + // Don't need to do anything for a destination endpoint. __weak reference in the messages handler will automatically nil out. } #pragma mark - Private diff --git a/Source/MIKMIDIEvent.h b/Source/MIKMIDIEvent.h index c60ddd73..fcea9c6c 100644 --- a/Source/MIKMIDIEvent.h +++ b/Source/MIKMIDIEvent.h @@ -8,6 +8,7 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" /** * Types of MIDI events. These values are used to determine which subclass to @@ -89,6 +90,8 @@ typedef NS_ENUM(NSUInteger, MIKMIDIMetaEventTypeType) MIKMIDIMetaEventTypeSequencerSpecificEvent = 0x7F }; +NS_ASSUME_NONNULL_BEGIN + /** * In MIKMIDI, MIDI events are objects. Specifically, they are instances of MIKMIDIEvent or one of its * subclasses. MIKMIDIEvent's subclasses each represent a specific type of MIDI event, for example, @@ -155,7 +158,7 @@ typedef NS_ENUM(NSUInteger, MIKMIDIMetaEventTypeType) * * @see +mikEventTypeForMusicEventType: */ -+ (instancetype)midiEventWithTimeStamp:(MusicTimeStamp)timeStamp eventType:(MusicEventType)eventType data:(NSData *)data; ++ (nullable instancetype)midiEventWithTimeStamp:(MusicTimeStamp)timeStamp eventType:(MusicEventType)eventType data:(nullable NSData *)data; /** * Initializes a new MIKMIDIEvent subclass instance. This method may return an instance of a different class than the @@ -168,7 +171,7 @@ typedef NS_ENUM(NSUInteger, MIKMIDIMetaEventTypeType) * @return For supported command types, an initialized MIKMIDIEvent subclass. Otherwise, an instance of * MIKMIDICommand itself. nil if there is an error. */ -- (instancetype)initWithTimeStamp:(MusicTimeStamp)timeStamp midiEventType:(MIKMIDIEventType)eventType data:(NSData *)data NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithTimeStamp:(MusicTimeStamp)timeStamp midiEventType:(MIKMIDIEventType)eventType data:(nullable NSData *)data NS_DESIGNATED_INITIALIZER; /** * The MIDI event type. @@ -196,18 +199,24 @@ typedef NS_ENUM(NSUInteger, MIKMIDIMetaEventTypeType) @property (nonatomic, readonly) MIKMIDIEventType eventType; @property (nonatomic) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @end +NS_ASSUME_NONNULL_END + #pragma mark - MIKMIDICommand+MIKMIDIEventToCommands #import @class MIKMIDIClock; +NS_ASSUME_NONNULL_BEGIN + @interface MIKMIDICommand (MIKMIDIEventToCommands) + (NSArray *)commandsFromMIDIEvent:(MIKMIDIEvent *)event clock:(MIKMIDIClock *)clock; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIEvent.m b/Source/MIKMIDIEvent.m index 37767edf..0b125734 100644 --- a/Source/MIKMIDIEvent.m +++ b/Source/MIKMIDIEvent.m @@ -253,7 +253,7 @@ - (NSData *)data { return [self.internalData copy]; } - (void)setData:(NSData *)data { if (![[self class] isMutable]) return MIKMIDI_RAISE_MUTATION_ATTEMPT_EXCEPTION; - self.internalData = [data mutableCopy]; + self.internalData = data ? [data mutableCopy] : [NSMutableData data]; } - (void)setTimeStamp:(MusicTimeStamp)timeStamp @@ -262,6 +262,13 @@ - (void)setTimeStamp:(MusicTimeStamp)timeStamp _timeStamp = timeStamp; } +- (void)setInternalData:(NSMutableData *)internalData +{ + if (internalData != _internalData) { + _internalData = internalData ? [internalData mutableCopy] : [NSMutableData data]; + } +} + @end @implementation MIKMutableMIDIEvent diff --git a/Source/MIKMIDIEventIterator.h b/Source/MIKMIDIEventIterator.h index 61e2c958..21f09642 100644 --- a/Source/MIKMIDIEventIterator.h +++ b/Source/MIKMIDIEventIterator.h @@ -8,10 +8,13 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDITrack; @class MIKMIDIEvent; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIEventIterator is an Objective-C wrapper for CoreMIDI's MusicEventIterator. It is not intended for use by clients/users of * of MIKMIDI. Rather, it should be thought of as an MIKMIDI private class. @@ -21,10 +24,10 @@ @property (nonatomic, readonly) BOOL hasPreviousEvent; @property (nonatomic, readonly) BOOL hasCurrentEvent; @property (nonatomic, readonly) BOOL hasNextEvent; -@property (nonatomic, readonly) MIKMIDIEvent *currentEvent; +@property (nonatomic, readonly, nullable) MIKMIDIEvent *currentEvent; -- (instancetype)initWithTrack:(MIKMIDITrack *)track; -+ (instancetype)iteratorForTrack:(MIKMIDITrack *)track; +- (nullable instancetype)initWithTrack:(MIKMIDITrack *)track; ++ (nullable instancetype)iteratorForTrack:(MIKMIDITrack *)track; - (BOOL)seek:(MusicTimeStamp)timeStamp; - (BOOL)moveToNextEvent; @@ -33,3 +36,5 @@ - (BOOL)moveCurrentEventTo:(MusicTimeStamp)timestamp error:(NSError **)error; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIEvent_SubclassMethods.h b/Source/MIKMIDIEvent_SubclassMethods.h index e5a4ef47..49c45ea3 100644 --- a/Source/MIKMIDIEvent_SubclassMethods.h +++ b/Source/MIKMIDIEvent_SubclassMethods.h @@ -6,6 +6,10 @@ // Copyright (c) 2014 Mixed In Key. All rights reserved. // +#import "MIKMIDIEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDIEvent () @@ -77,15 +81,12 @@ * data property. Subclasses may set it. When mutating it, subclasses should manually * call -will/didChangeValueForKey for the internalData key path. */ -@property (nonatomic, strong, readwrite) NSMutableData *internalData; +@property (nonatomic, strong /* mutableCopy*/, readwrite) NSMutableData *internalData; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) MIKMIDIEventType eventType; -@property (nonatomic, strong, readwrite) NSData *metaData; - - /** * Additional description string to be appended to basic description provided by * -[MIKMIDIEvent description]. Subclasses of MIKMIDIEvent can override this @@ -109,4 +110,6 @@ */ + (BOOL)supportsMIKMIDIEventType:(MIKMIDIEventType)type DEPRECATED_ATTRIBUTE; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIInputPort.m b/Source/MIKMIDIInputPort.m index 7aab44ee..f0cfab66 100644 --- a/Source/MIKMIDIInputPort.m +++ b/Source/MIKMIDIInputPort.m @@ -40,7 +40,7 @@ @interface MIKMIDIInputPort () @implementation MIKMIDIInputPort -- (id)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name +- (instancetype)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name { self = [super initWithClient:clientRef name:name]; if (self) { diff --git a/Source/MIKMIDIMappableResponder.h b/Source/MIKMIDIMappableResponder.h index 478e4811..4966ba54 100644 --- a/Source/MIKMIDIMappableResponder.h +++ b/Source/MIKMIDIMappableResponder.h @@ -8,6 +8,7 @@ #import #import "MIKMIDIResponder.h" +#import "MIKMIDICompilerCompatibility.h" /** * Bit-mask constants used to specify MIDI responder types for mapping. @@ -82,6 +83,8 @@ typedef NS_OPTIONS(NSUInteger, MIKMIDIResponderType){ MIKMIDIResponderTypeAll = NSUIntegerMax, }; +NS_ASSUME_NONNULL_BEGIN + /** * This protocol defines methods that that must be implemented by MIDI responder objects to be mapped * using MIKMIDIMappingGenerator, and to whom MIDI messages will selectively be routed using a MIDI mapping @@ -142,3 +145,5 @@ typedef NS_OPTIONS(NSUInteger, MIKMIDIResponderType){ - (BOOL)illuminationStateForCommandIdentifier:(NSString *)commandID; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMapping.h b/Source/MIKMIDIMapping.h index 6afd4d8d..fb0613f9 100644 --- a/Source/MIKMIDIMapping.h +++ b/Source/MIKMIDIMapping.h @@ -7,6 +7,7 @@ // #import +#import "MIKMIDICompilerCompatibility.h" #import "MIKMIDICommand.h" #import "MIKMIDIResponder.h" @@ -16,6 +17,8 @@ @class MIKMIDIChannelVoiceCommand; @class MIKMIDIMappingItem; +NS_ASSUME_NONNULL_BEGIN + /** * Overview * -------- @@ -79,27 +82,12 @@ /** * Initializes and returns an MIKMIDIMapping object created from the XML file at url. * - * @note This method is currently only available on OS X. See https://github.com/mixedinkey-opensource/MIKMIDI/issues/2 - * * @param url An NSURL for the file to be read. * @param error If an error occurs, upon returns contains an NSError object that describes the problem. If you are not interested in possible errors, you may pass in NULL. * * @return An initialized MIKMIDIMapping instance, or nil if an error occurred. */ -- (instancetype)initWithFileAtURL:(NSURL *)url error:(NSError **)error; - -/** - * Initializes and returns an MIKMIDIMapping object created from the XML file at url. - * - * @note This method is currently only available on OS X. See https://github.com/mixedinkey-opensource/MIKMIDI/issues/2 - * - * @param url An NSURL for the file to be read. - * - * @return An initialized MIKMIDIMapping instance, or nil if an error occurred. - * - * @see -initWithFileAtURL:error: - */ -- (instancetype)initWithFileAtURL:(NSURL *)url; +- (nullable instancetype)initWithFileAtURL:(NSURL *)url error:(NSError **)error; /** * Creates and initializes an MIKMIDIMapping object that is the same as the passed in bundled mapping @@ -132,11 +120,11 @@ * Returns an NSString instance containing an XML representation of the receiver. * The XML document returned by this method can be written to disk. * - * @return An NSString containing an XML representation of the receiver. + * @return An NSString containing an XML representation of the receiver, or nil if an error occurred. * * @see -writeToFileAtURL:error: */ -- (NSString *)XMLStringRepresentation; +- (nullable NSString *)XMLStringRepresentation; /** * Writes the receiver as an XML file to the specified URL. @@ -220,7 +208,7 @@ /** * Optional additional key value pairs, which will be saved as attributes in this mapping's XML representation. Keys and values must be NSStrings. */ -@property (nonatomic, copy) NSDictionary *additionalAttributes; +@property (nonatomic, copy, nullable) NSDictionary *additionalAttributes; /** * All mapping items this mapping contains. @@ -256,3 +244,23 @@ - (void)removeMappingItems:(NSSet *)mappingItems; @end + +#pragma mark - + +@interface MIKMIDIMapping (Deprecated) + +/** + * @deprecated Use -initWithFileAtURL:error: instead. + * Initializes and returns an MIKMIDIMapping object created from the XML file at url. + * + * @param url An NSURL for the file to be read. + * + * @return An initialized MIKMIDIMapping instance, or nil if an error occurred. + * + * @see -initWithFileAtURL:error: + */ +- (nullable instancetype)initWithFileAtURL:(NSURL *)url DEPRECATED_ATTRIBUTE; + +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMapping.m b/Source/MIKMIDIMapping.m index af70b29d..a42e10a8 100644 --- a/Source/MIKMIDIMapping.m +++ b/Source/MIKMIDIMapping.m @@ -45,11 +45,6 @@ @interface MIKMIDIMapping () @implementation MIKMIDIMapping -- (instancetype)initWithFileAtURL:(NSURL *)url -{ - return [self initWithFileAtURL:url error:NULL]; -} - - (instancetype)initWithFileAtURL:(NSURL *)url error:(NSError **)error; { error = error ? error : &(NSError *__autoreleasing){ nil }; @@ -94,7 +89,7 @@ - (id)init { self = [super init]; if (self) { - self.internalMappingItems = [NSMutableSet set]; + _internalMappingItems = [NSMutableSet set]; } return self; } @@ -466,3 +461,14 @@ - (NSString *)name } @end + +#pragma mark - + +@implementation MIKMIDIMapping (Deprecated) + +- (instancetype)initWithFileAtURL:(NSURL *)url +{ + return [self initWithFileAtURL:url error:NULL]; +} + +@end \ No newline at end of file diff --git a/Source/MIKMIDIMappingGenerator.h b/Source/MIKMIDIMappingGenerator.h index b71226b9..e466781f 100644 --- a/Source/MIKMIDIMappingGenerator.h +++ b/Source/MIKMIDIMappingGenerator.h @@ -7,7 +7,7 @@ // #import -//#import "MIKMIDIPrivate.h" +#import "MIKMIDICompilerCompatibility.h" #import "MIKMIDIMapping.h" @@ -17,6 +17,8 @@ @protocol MIKMIDIMappingGeneratorDelegate; +NS_ASSUME_NONNULL_BEGIN + /** * Completion block for mapping generation method. * @@ -24,7 +26,7 @@ * @param messages The messages used to generate the mapping. May not include all messages received during mapping. * @param error If mapping failed, an NSError explaing the failure, nil if mapping succeeded. */ -typedef void(^MIKMIDIMappingGeneratorMappingCompletionBlock)(MIKMIDIMappingItem *mappingItem, NSArray *messages, NSError *error); +typedef void(^MIKMIDIMappingGeneratorMappingCompletionBlock)(MIKMIDIMappingItem *mappingItem, NSArray *messages, NSError *_Nullable error); /** * MIKMIDIMappingGenerator is used to map incoming commands from a MIDI device to MIDI responders in an application. @@ -124,9 +126,9 @@ typedef void(^MIKMIDIMappingGeneratorMappingCompletionBlock)(MIKMIDIMappingItem @property (nonatomic, MIKMIDIMappingGeneratorWeakProperty) id delegate; /** - * The device for which a mapping is being generated. Must not be nil. + * The device for which a mapping is being generated. Must not be nil for mapping to work. */ -@property (nonatomic, strong) MIKMIDIDevice *device; +@property (nonatomic, strong, nullable) MIKMIDIDevice *device; /** * The mapping being generated. Assign before mapping starts to modify existing mapping. @@ -233,4 +235,6 @@ shouldRemoveExistingMappingItems:(NSSet *)mappingItems - (MIKMIDIChannelVoiceCommand *)mappingGenerator:(MIKMIDIMappingGenerator *)generator commandByProcessingIncomingCommand:(MIKMIDIChannelVoiceCommand *)command; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMappingGenerator.m b/Source/MIKMIDIMappingGenerator.m index ab1c27c5..7763904f 100644 --- a/Source/MIKMIDIMappingGenerator.m +++ b/Source/MIKMIDIMappingGenerator.m @@ -80,11 +80,9 @@ - (instancetype)initWithDevice:(MIKMIDIDevice *)device error:(NSError **)error; return self; } -- (id)init +- (id)init NS_UNAVAILABLE { [NSException raise:NSInternalInconsistencyException format:@"-initWithDevice: is the designated initializer for %@", NSStringFromClass([self class])]; - self = [self initWithDevice:nil error:NULL]; // Keep the compiler happy - [self self]; // Keep the compiler happy part 2 return nil; } diff --git a/Source/MIKMIDIMappingItem.h b/Source/MIKMIDIMappingItem.h index f9dfaaff..fcf8b21f 100644 --- a/Source/MIKMIDIMappingItem.h +++ b/Source/MIKMIDIMappingItem.h @@ -9,9 +9,12 @@ #import #import "MIKMIDIMappableResponder.h" #import "MIKMIDICommand.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIMapping; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIMappingItem contains information about a mapping between a physical MIDI control, * and a single command supported by a particular MIDI responder object. @@ -38,11 +41,11 @@ * Returns an NSString instance containing an XML representation of the receiver. * The XML document returned by this method can be written to disk. * - * @return An NSString containing an XML representation of the receiver. + * @return An NSString containing an XML representation of the receiver, or nil if an error occurred. * * @see -writeToFileAtURL:error: */ -- (NSString *)XMLStringRepresentation; +- (nullable NSString *)XMLStringRepresentation; // Properties @@ -92,12 +95,14 @@ /** * Optional additional key value pairs, which will be saved as attributes in this item's XML representation. Keys and values must be NSStrings. */ -@property (nonatomic, copy) NSDictionary *additionalAttributes; +@property (nonatomic, copy, nullable) NSDictionary *additionalAttributes; /** * The MIDI Mapping the receiver belongs to. May be nil if the mappping item hasn't been added to a mapping yet, * or its mapping has been deallocated. */ -@property (nonatomic, weak, readonly) MIKMIDIMapping *mapping; +@property (nonatomic, weak, readonly, nullable) MIKMIDIMapping *mapping; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMappingManager.h b/Source/MIKMIDIMappingManager.h index 995feacb..293daa6a 100644 --- a/Source/MIKMIDIMappingManager.h +++ b/Source/MIKMIDIMappingManager.h @@ -7,11 +7,14 @@ // #import +#import "MIKMIDICompilerCompatibility.h" #define kMIKMIDIMappingFileExtension @"midimap" @class MIKMIDIMapping; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIMappingManager provides a centralized way to manage an application's * MIDI mappings. It handles both bundled (built in) mapping files, as well @@ -91,7 +94,7 @@ * * @return An MIKMIDIMapping instance for the imported file, or nil if there was an error. */ -- (MIKMIDIMapping *)importMappingFromFileAtURL:(NSURL *)URL overwritingExistingMapping:(BOOL)shouldOverwrite error:(NSError **)error; +- (nullable MIKMIDIMapping *)importMappingFromFileAtURL:(NSURL *)URL overwritingExistingMapping:(BOOL)shouldOverwrite error:(NSError **)error; /** * Saves user mappings to disk. These mappings are currently saved to a folder at //MIDI Mappings. @@ -155,6 +158,8 @@ * * @deprecated Deprecated. Use -mappingsWithName: instead. */ -- (MIKMIDIMapping *)mappingWithName:(NSString *)mappingName DEPRECATED_ATTRIBUTE; +- (nullable MIKMIDIMapping *)mappingWithName:(NSString *)mappingName DEPRECATED_ATTRIBUTE; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMappingManager.m b/Source/MIKMIDIMappingManager.m index 062cab1f..60a4e52a 100644 --- a/Source/MIKMIDIMappingManager.m +++ b/Source/MIKMIDIMappingManager.m @@ -226,7 +226,12 @@ - (void)loadAvailableUserMappings if (![[file pathExtension] isEqualToString:kMIKMIDIMappingFileExtension]) continue; // process the mapping file - MIKMIDIMapping *mapping = [[MIKMIDIMapping alloc] initWithFileAtURL:file]; + NSError *error = nil; + MIKMIDIMapping *mapping = [[MIKMIDIMapping alloc] initWithFileAtURL:file error:&error]; + if (!mapping) { + NSLog(@"Error loading MIDI mapping from %@: %@", file, error); + continue; + } if (mapping) [mappings addObject:mapping]; } } else { @@ -243,7 +248,12 @@ - (void)loadBundledMappings NSBundle *bundle = [NSBundle mainBundle]; NSArray *bundledMappingFileURLs = [bundle URLsForResourcesWithExtension:kMIKMIDIMappingFileExtension subdirectory:nil]; for (NSURL *file in bundledMappingFileURLs) { - MIKMIDIMapping *mapping = [[MIKMIDIMapping alloc] initWithFileAtURL:file]; + NSError *error = nil; + MIKMIDIMapping *mapping = [[MIKMIDIMapping alloc] initWithFileAtURL:file error:&error]; + if (!mapping) { + NSLog(@"Error loading MIDI mapping from %@: %@", file, error); + continue; + } mapping.bundledMapping = YES; if (mapping) [mappings addObject:mapping]; } diff --git a/Source/MIKMIDIMappingManager_SubclassMethods.h b/Source/MIKMIDIMappingManager_SubclassMethods.h index d6855266..0788118b 100644 --- a/Source/MIKMIDIMappingManager_SubclassMethods.h +++ b/Source/MIKMIDIMappingManager_SubclassMethods.h @@ -8,9 +8,11 @@ #import "MIKMIDIMappingManager.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIMapping; +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDIMappingManager () @@ -38,6 +40,8 @@ * * @return An array of legacy file names, or nil. */ -- (NSArray *)legacyFileNamesForUserMappingsObject:(MIKMIDIMapping *)mapping; +- (nullable NSArray *)legacyFileNamesForUserMappingsObject:(MIKMIDIMapping *)mapping; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMappingXMLParser.h b/Source/MIKMIDIMappingXMLParser.h index 5bdf5a8e..f699cdc6 100644 --- a/Source/MIKMIDIMappingXMLParser.h +++ b/Source/MIKMIDIMappingXMLParser.h @@ -7,9 +7,12 @@ // #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIMapping; +NS_ASSUME_NONNULL_BEGIN + /** * A parser for XML MIDI mapping files. Only used on iOS. On OS X, NSXMLDocument is used * directly instead. Should be considered "private" for use by MIKMIDIMapping. @@ -22,3 +25,5 @@ @property (nonatomic, strong, readonly) NSArray *mappings; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMappingXMLParser.m b/Source/MIKMIDIMappingXMLParser.m index 5be67ef6..29daa56a 100644 --- a/Source/MIKMIDIMappingXMLParser.m +++ b/Source/MIKMIDIMappingXMLParser.m @@ -42,7 +42,9 @@ + (instancetype)parserWithXMLData:(NSData *)xmlData - (instancetype)initWithXMLData:(NSData *)xmlData { - if (![xmlData length]) return nil; + if (![xmlData length]) { + [NSException raise:NSInvalidArgumentException format:"Argument passed to -[%@ %@] must have a non-zero length.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + } self = [super init]; if (self) { @@ -160,7 +162,7 @@ - (void)parserDidEndDocument:(NSXMLParser *)parser - (NSArray *)mappings { if (!self.hasParsed) [self parse]; - return _mappings; + return _mappings ?: @[]; } @end diff --git a/Source/MIKMIDIMetaCopyrightEvent.h b/Source/MIKMIDIMetaCopyrightEvent.h index 36de74e5..b096106e 100644 --- a/Source/MIKMIDIMetaCopyrightEvent.h +++ b/Source/MIKMIDIMetaCopyrightEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing copyright information. @@ -22,6 +25,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaCuePointEvent.h b/Source/MIKMIDIMetaCuePointEvent.h index f9861002..d2de0268 100644 --- a/Source/MIKMIDIMetaCuePointEvent.h +++ b/Source/MIKMIDIMetaCuePointEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing cue point information. @@ -22,6 +25,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaEvent.h b/Source/MIKMIDIMetaEvent.h index b931ad77..d7edec4c 100644 --- a/Source/MIKMIDIMetaEvent.h +++ b/Source/MIKMIDIMetaEvent.h @@ -7,9 +7,12 @@ // #import "MIKMIDIEvent.h" +#import "MIKMIDICompilerCompatibility.h" #define MIKMIDIEventMetadataStartOffset 8 +NS_ASSUME_NONNULL_BEGIN + /** * A MIDI meta event. */ @@ -40,6 +43,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaEvent.m b/Source/MIKMIDIMetaEvent.m index 0e96286d..c3e56060 100644 --- a/Source/MIKMIDIMetaEvent.m +++ b/Source/MIKMIDIMetaEvent.m @@ -73,7 +73,7 @@ - (void)setMetaData:(NSData *)metaData metaEvent->dataLength = (UInt32)[metaData length]; NSMutableData *newMetaData = [[self.internalData subdataWithRange:NSMakeRange(0, MIKMIDIEventMetadataStartOffset)] mutableCopy]; [newMetaData appendData:metaData]; - self.internalData = newMetaData; + self.internalData = newMetaData ?: [NSMutableData data]; } @end diff --git a/Source/MIKMIDIMetaEvent_SubclassMethods.h b/Source/MIKMIDIMetaEvent_SubclassMethods.h new file mode 100644 index 00000000..fb9998e8 --- /dev/null +++ b/Source/MIKMIDIMetaEvent_SubclassMethods.h @@ -0,0 +1,16 @@ +// +// MIKMIDIMetaEvent_SubclassMethods.h +// MIKMIDI +// +// Created by Andrew Madsen on 11/10/15. +// Copyright © 2015 Mixed In Key. All rights reserved. +// + +#import +#import "MIKMIDIEvent_SubclassMethods.h" + +@interface MIKMIDIMetaEvent () + +@property (nonatomic, strong, readwrite) NSData *metaData; + +@end diff --git a/Source/MIKMIDIMetaInstrumentNameEvent.h b/Source/MIKMIDIMetaInstrumentNameEvent.h index 34aac8bf..276a912b 100644 --- a/Source/MIKMIDIMetaInstrumentNameEvent.h +++ b/Source/MIKMIDIMetaInstrumentNameEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing an instrument name. @@ -23,6 +26,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaKeySignatureEvent.h b/Source/MIKMIDIMetaKeySignatureEvent.h index 3d004e9b..56b94107 100644 --- a/Source/MIKMIDIMetaKeySignatureEvent.h +++ b/Source/MIKMIDIMetaKeySignatureEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing key signature information. @@ -33,8 +36,10 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; @property (nonatomic, readwrite) UInt8 key; @property (nonatomic, readwrite) UInt8 scale; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaKeySignatureEvent.m b/Source/MIKMIDIMetaKeySignatureEvent.m index 00303e7d..2b5e7f08 100644 --- a/Source/MIKMIDIMetaKeySignatureEvent.m +++ b/Source/MIKMIDIMetaKeySignatureEvent.m @@ -7,7 +7,7 @@ // #import "MIKMIDIMetaKeySignatureEvent.h" -#import "MIKMIDIEvent_SubclassMethods.h" +#import "MIKMIDIMetaEvent_SubclassMethods.h" #import "MIKMIDIUtilities.h" #if !__has_feature(objc_arc) diff --git a/Source/MIKMIDIMetaLyricEvent.h b/Source/MIKMIDIMetaLyricEvent.h index d19bcfef..ae3fe3cb 100644 --- a/Source/MIKMIDIMetaLyricEvent.h +++ b/Source/MIKMIDIMetaLyricEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing lyrics. @@ -22,6 +25,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaMarkerTextEvent.h b/Source/MIKMIDIMetaMarkerTextEvent.h index 358a9132..2a47a757 100644 --- a/Source/MIKMIDIMetaMarkerTextEvent.h +++ b/Source/MIKMIDIMetaMarkerTextEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing marker information. @@ -22,6 +25,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaSequenceEvent.h b/Source/MIKMIDIMetaSequenceEvent.h index e2aa1f3f..2ea9b8e2 100644 --- a/Source/MIKMIDIMetaSequenceEvent.h +++ b/Source/MIKMIDIMetaSequenceEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing sequence information. @@ -22,6 +25,8 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaTextEvent.h b/Source/MIKMIDIMetaTextEvent.h index 271de1b0..3c1db46a 100644 --- a/Source/MIKMIDIMetaTextEvent.h +++ b/Source/MIKMIDIMetaTextEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing text. @@ -16,7 +19,7 @@ /** * The text for the event. */ -@property (nonatomic, readonly) NSString *string; +@property (nonatomic, readonly, nullable) NSString *string; @end @@ -27,7 +30,9 @@ @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; -@property (nonatomic, copy, readwrite) NSString *string; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; +@property (nonatomic, copy, readwrite, nullable) NSString *string; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaTextEvent.m b/Source/MIKMIDIMetaTextEvent.m index 2ff5d018..39c085fc 100644 --- a/Source/MIKMIDIMetaTextEvent.m +++ b/Source/MIKMIDIMetaTextEvent.m @@ -7,7 +7,7 @@ // #import "MIKMIDIMetaTextEvent.h" -#import "MIKMIDIEvent_SubclassMethods.h" +#import "MIKMIDIMetaEvent_SubclassMethods.h" #import "MIKMIDIUtilities.h" #if !__has_feature(objc_arc) diff --git a/Source/MIKMIDIMetaTimeSignatureEvent.h b/Source/MIKMIDIMetaTimeSignatureEvent.h index 3810d182..a4692dd7 100644 --- a/Source/MIKMIDIMetaTimeSignatureEvent.h +++ b/Source/MIKMIDIMetaTimeSignatureEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIMetaEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing time signature information. @@ -41,11 +44,13 @@ @interface MIKMutableMIDIMetaTimeSignatureEvent : MIKMIDIMetaTimeSignatureEvent @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 numerator; @property (nonatomic, readwrite) UInt8 denominator; @property (nonatomic, readwrite) UInt8 metronomePulse; @property (nonatomic, readwrite) UInt8 thirtySecondsPerQuarterNote; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetaTimeSignatureEvent.m b/Source/MIKMIDIMetaTimeSignatureEvent.m index c5561bae..16ff81ba 100644 --- a/Source/MIKMIDIMetaTimeSignatureEvent.m +++ b/Source/MIKMIDIMetaTimeSignatureEvent.m @@ -7,7 +7,7 @@ // #import "MIKMIDIMetaTimeSignatureEvent.h" -#import "MIKMIDIEvent_SubclassMethods.h" +#import "MIKMIDIMetaEvent_SubclassMethods.h" #import "MIKMIDIUtilities.h" #if !__has_feature(objc_arc) diff --git a/Source/MIKMIDIMetaTrackSequenceNameEvent.h b/Source/MIKMIDIMetaTrackSequenceNameEvent.h index 42883361..a037792a 100644 --- a/Source/MIKMIDIMetaTrackSequenceNameEvent.h +++ b/Source/MIKMIDIMetaTrackSequenceNameEvent.h @@ -7,13 +7,16 @@ // #import "MIKMIDIMetaTextEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A meta event containing a track name. */ @interface MIKMIDIMetaTrackSequenceNameEvent : MIKMIDIMetaTextEvent -@property (nonatomic, readonly) NSString *name; +@property (nonatomic, readonly, nullable) NSString *name; @end @@ -22,11 +25,13 @@ */ @interface MIKMutableMIDIMetaTrackSequenceNameEvent : MIKMIDIMetaTrackSequenceNameEvent -@property (nonatomic, copy, readwrite) NSString *name; +@property (nonatomic, copy, readwrite, nullable) NSString *name; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; @property (nonatomic, readwrite) UInt8 metadataType; -@property (nonatomic, strong, readwrite) NSData *metaData; +@property (nonatomic, strong, readwrite, null_resettable) NSData *metaData; @property (nonatomic, copy, readwrite) NSString *string; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIMetronome.h b/Source/MIKMIDIMetronome.h index 37a15072..4cebe7cf 100644 --- a/Source/MIKMIDIMetronome.h +++ b/Source/MIKMIDIMetronome.h @@ -7,7 +7,9 @@ // #import "MIKMIDIEndpointSynthesizer.h" +#import "MIKMIDICompilerCompatibility.h" +NS_ASSUME_NONNULL_BEGIN /** * This class is only a subclass of MIKMIDIEndpointSynthesizer so it continues to function with MIKMIDIPlayer while @@ -29,4 +31,6 @@ */ - (BOOL)setupMetronome; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDINoteEvent.h b/Source/MIKMIDINoteEvent.h index 61986c7c..30aa6701 100644 --- a/Source/MIKMIDINoteEvent.h +++ b/Source/MIKMIDINoteEvent.h @@ -7,9 +7,12 @@ // #import "MIKMIDIEvent.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIClock; +NS_ASSUME_NONNULL_BEGIN + /** * A MIDI note event. */ @@ -26,11 +29,11 @@ * * @return An initialized MIKMIDINoteEvent instance, or nil if an error occurred. */ -+ (instancetype)noteEventWithTimeStamp:(MusicTimeStamp)timeStamp - note:(UInt8)note - velocity:(UInt8)velocity - duration:(Float32)duration - channel:(UInt8)channel; ++ (nullable instancetype)noteEventWithTimeStamp:(MusicTimeStamp)timeStamp + note:(UInt8)note + velocity:(UInt8)velocity + duration:(Float32)duration + channel:(UInt8)channel; /** * Convenience method for creating a new MIKMIDINoteEvent from a CoreMIDI MIDINoteMessage struct. @@ -40,7 +43,7 @@ * * @return A new MIKMIDINoteEvent instance, or nil if there is an error. */ -+ (instancetype)noteEventWithTimeStamp:(MusicTimeStamp)timeStamp message:(MIDINoteMessage)message; ++ (nullable instancetype)noteEventWithTimeStamp:(MusicTimeStamp)timeStamp message:(MIDINoteMessage)message; // Properties @@ -99,7 +102,7 @@ @interface MIKMutableMIDINoteEvent : MIKMIDINoteEvent @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 note; @property (nonatomic, readwrite) UInt8 velocity; @property (nonatomic, readwrite) UInt8 channel; @@ -108,15 +111,21 @@ @end +NS_ASSUME_NONNULL_END + #pragma mark - #import #import +NS_ASSUME_NONNULL_BEGIN + @interface MIKMIDICommand (MIKMIDINoteEventToCommands) + (NSArray *)commandsFromNoteEvent:(MIKMIDINoteEvent *)noteEvent clock:(MIKMIDIClock *)clock; + (MIKMIDINoteOnCommand *)noteOnCommandFromNoteEvent:(MIKMIDINoteEvent *)noteEvent clock:(MIKMIDIClock *)clock; + (MIKMIDINoteOffCommand *)noteOffCommandFromNoteEvent:(MIKMIDINoteEvent *)noteEvent clock:(MIKMIDIClock *)clock; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDINoteOffCommand.h b/Source/MIKMIDINoteOffCommand.h index 869dd567..1685a9ee 100644 --- a/Source/MIKMIDINoteOffCommand.h +++ b/Source/MIKMIDINoteOffCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelVoiceCommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI note off message. @@ -26,7 +29,7 @@ + (instancetype)noteOffCommandWithNote:(NSUInteger)note velocity:(NSUInteger)velocity channel:(UInt8)channel - timestamp:(NSDate *)timestamp; + timestamp:(nullable NSDate *)timestamp; /** * The note number for the message. In the range 0-127. @@ -53,4 +56,6 @@ @property (nonatomic, readwrite) NSUInteger note; @property (nonatomic, readwrite) NSUInteger velocity; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDINoteOnCommand.h b/Source/MIKMIDINoteOnCommand.h index b7f023b6..2ef9aae1 100644 --- a/Source/MIKMIDINoteOnCommand.h +++ b/Source/MIKMIDINoteOnCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelVoiceCommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI note on message. @@ -26,7 +29,7 @@ + (instancetype)noteOnCommandWithNote:(NSUInteger)note velocity:(NSUInteger)velocity channel:(UInt8)channel - timestamp:(NSDate *)timestamp; + timestamp:(nullable NSDate *)timestamp; /** * The note number for the message. In the range 0-127. @@ -54,3 +57,5 @@ @property (nonatomic, readwrite) NSUInteger velocity; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIObject_SubclassMethods.h b/Source/MIKMIDIObject_SubclassMethods.h index 1e3544d3..bbf9c60c 100644 --- a/Source/MIKMIDIObject_SubclassMethods.h +++ b/Source/MIKMIDIObject_SubclassMethods.h @@ -7,6 +7,9 @@ // #import "MIKMIDIObject.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * These methods can be called and/or overridden by subclasses of MIKMIDIObject, but are not @@ -55,3 +58,5 @@ @property (nonatomic, readwrite) BOOL isVirtual; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIOutputPort.h b/Source/MIKMIDIOutputPort.h index ee5c6d5a..0b4c740b 100644 --- a/Source/MIKMIDIOutputPort.h +++ b/Source/MIKMIDIOutputPort.h @@ -7,10 +7,13 @@ // #import "MIKMIDIPort.h" +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDICommand; @class MIKMIDIDestinationEndpoint; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIOutputPort is an Objective-C wrapper for CoreMIDI's MIDIPort class, and is only for destination ports. * It is not intended for use by clients/users of of MIKMIDI. Rather, it should be thought of as an @@ -21,3 +24,5 @@ - (BOOL)sendCommands:(NSArray *)commands toDestination:(MIKMIDIDestinationEndpoint *)destination error:(NSError **)error; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIOutputPort.m b/Source/MIKMIDIOutputPort.m index 091af2c5..70f77ced 100644 --- a/Source/MIKMIDIOutputPort.m +++ b/Source/MIKMIDIOutputPort.m @@ -17,7 +17,7 @@ @implementation MIKMIDIOutputPort -- (id)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name +- (instancetype)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name { self = [super initWithClient:clientRef name:name]; if (self) { diff --git a/Source/MIKMIDIPitchBendChangeCommand.h b/Source/MIKMIDIPitchBendChangeCommand.h index 758e62cd..65bda0a0 100644 --- a/Source/MIKMIDIPitchBendChangeCommand.h +++ b/Source/MIKMIDIPitchBendChangeCommand.h @@ -7,6 +7,9 @@ // #import +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI pitch bend change command. @@ -37,6 +40,8 @@ @property (nonatomic, readwrite) UInt8 dataByte2; @property (nonatomic, readwrite) MIDITimeStamp midiTimestamp; -@property (nonatomic, copy, readwrite) NSData *data; +@property (nonatomic, copy, readwrite, null_resettable) NSData *data; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIPitchBendChangeEvent.h b/Source/MIKMIDIPitchBendChangeEvent.h index 36db4e01..2c84e07f 100644 --- a/Source/MIKMIDIPitchBendChangeEvent.h +++ b/Source/MIKMIDIPitchBendChangeEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A pitch bed change event. @@ -33,9 +36,11 @@ @property (nonatomic, readonly) UInt16 pitchChange; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIPlayer.h b/Source/MIKMIDIPlayer.h index b6c5a257..79b08225 100644 --- a/Source/MIKMIDIPlayer.h +++ b/Source/MIKMIDIPlayer.h @@ -8,10 +8,13 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDISequence; @class MIKMIDIMetronome; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIPlayer can be used to play an MIKMIDISequence. */ @@ -53,7 +56,7 @@ __attribute((deprecated("use MIKMIDISequencer instead"))) /** * The music sequence to play. */ -@property (strong, nonatomic) MIKMIDISequence *sequence; +@property (strong, nonatomic, nullable) MIKMIDISequence *sequence; /** * The current position in the music sequence. @@ -80,10 +83,12 @@ __attribute((deprecated("use MIKMIDISequencer instead"))) @property (nonatomic, getter=isLooping) BOOL looping; @property (nonatomic, getter=isClickTrackEnabled) BOOL clickTrackEnabled; -@property (strong, nonatomic) MIKMIDIMetronome *metronome; +@property (strong, nonatomic, nullable) MIKMIDIMetronome *metronome; @property (nonatomic) BOOL stopPlaybackAtEndOfSequence; @property (nonatomic) MusicTimeStamp maxClickTrackTimeStamp; @end + +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDIPolyphonicKeyPressureEvent.h b/Source/MIKMIDIPolyphonicKeyPressureEvent.h index 58c78275..132317da 100644 --- a/Source/MIKMIDIPolyphonicKeyPressureEvent.h +++ b/Source/MIKMIDIPolyphonicKeyPressureEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A polyphonic key pressure (aftertouch) event. @@ -36,9 +39,11 @@ @property (nonatomic, readwrite) UInt8 pressure; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIPort.h b/Source/MIKMIDIPort.h index 081af502..e1cc52bb 100644 --- a/Source/MIKMIDIPort.h +++ b/Source/MIKMIDIPort.h @@ -8,17 +8,22 @@ #import "MIKMIDIObject.h" #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIEndpoint; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDIPort is an Objective-C wrapper for CoreMIDI's MIDIPort class. It is not intended for use by clients/users of * of MIKMIDI. Rather, it should be thought of as an MIKMIDI private class. */ @interface MIKMIDIPort : NSObject -- (id)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name; +- (nullable instancetype)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name; @property (nonatomic, readonly) MIDIPortRef portRef; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIPort.m b/Source/MIKMIDIPort.m index 484ec886..b9a91bec 100644 --- a/Source/MIKMIDIPort.m +++ b/Source/MIKMIDIPort.m @@ -16,7 +16,7 @@ @implementation MIKMIDIPort -- (id)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name +- (instancetype)initWithClient:(MIDIClientRef)clientRef name:(NSString *)name { self = [super init]; if (self) { diff --git a/Source/MIKMIDIPort_SubclassMethods.h b/Source/MIKMIDIPort_SubclassMethods.h index 9ef4fd05..282bfe10 100644 --- a/Source/MIKMIDIPort_SubclassMethods.h +++ b/Source/MIKMIDIPort_SubclassMethods.h @@ -7,6 +7,9 @@ // #import "MIKMIDIPort.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDIPort () @@ -14,3 +17,4 @@ @end +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIPrivateUtilities.h b/Source/MIKMIDIPrivateUtilities.h index acf41de2..df1bf0ac 100644 --- a/Source/MIKMIDIPrivateUtilities.h +++ b/Source/MIKMIDIPrivateUtilities.h @@ -7,8 +7,13 @@ // #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDIChannelVoiceCommand; +NS_ASSUME_NONNULL_BEGIN + NSUInteger MIKMIDIControlNumberFromCommand(MIKMIDIChannelVoiceCommand *command); float MIKMIDIControlValueFromChannelVoiceCommand(MIKMIDIChannelVoiceCommand *command); + +NS_ASSUME_NONNULL_END diff --git a/Source/MIKMIDIProgramChangeCommand.h b/Source/MIKMIDIProgramChangeCommand.h index 5a1aad29..032422cc 100644 --- a/Source/MIKMIDIProgramChangeCommand.h +++ b/Source/MIKMIDIProgramChangeCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelVoiceCommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI program change message. @@ -34,4 +37,6 @@ @property (nonatomic, readwrite) NSUInteger programNumber; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIProgramChangeEvent.h b/Source/MIKMIDIProgramChangeEvent.h index 2133b48c..10b5c35a 100644 --- a/Source/MIKMIDIProgramChangeEvent.h +++ b/Source/MIKMIDIProgramChangeEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIChannelEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI program change event. @@ -40,9 +43,11 @@ @property (nonatomic, readwrite) NSUInteger programNumber; @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) UInt8 channel; @property (nonatomic, readwrite) UInt8 dataByte1; @property (nonatomic, readwrite) UInt8 dataByte2; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDIResponder.h b/Source/MIKMIDIResponder.h index be091319..4cba7517 100644 --- a/Source/MIKMIDIResponder.h +++ b/Source/MIKMIDIResponder.h @@ -7,9 +7,12 @@ // #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDICommand; +NS_ASSUME_NONNULL_BEGIN + /** * The MIKMIDIResponder protocol defines methods to be implemented by any object that wishes * to receive MIDI messages/commands. @@ -63,11 +66,13 @@ * application, as long as the receiver (or a parent responder) is registered. * * Should return a flat (non-recursive) array of subresponders. - * Return nil, empty array, or don't implement if you don't want subresponders to be + * Return empty array, or don't implement if you don't want subresponders to be * included in any case where the receiver would be considered for receiving MIDI * * @return An NSArray containing the receivers subresponders. Each object in the array must also conform to MIKMIDIResponder. */ -- (NSArray *)subresponders; +- (nullable NSArray *)subresponders; // Nullable for historical reasons. @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISequence+MIKMIDIPrivate.h b/Source/MIKMIDISequence+MIKMIDIPrivate.h index 1e4333da..a3da04c5 100644 --- a/Source/MIKMIDISequence+MIKMIDIPrivate.h +++ b/Source/MIKMIDISequence+MIKMIDIPrivate.h @@ -7,12 +7,16 @@ // #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDISequencer; +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDISequence (MIKMIDIPrivate) -@property (weak, nonatomic) MIKMIDISequencer *sequencer; +@property (weak, nonatomic, nullable) MIKMIDISequencer *sequencer; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISequence.h b/Source/MIKMIDISequence.h index 5a45258a..420edf1e 100644 --- a/Source/MIKMIDISequence.h +++ b/Source/MIKMIDISequence.h @@ -8,7 +8,7 @@ #import #import - +#import "MIKMIDICompilerCompatibility.h" typedef struct { UInt8 numerator; @@ -26,6 +26,8 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d @class MIKMIDISequencer; @class MIKMIDIDestinationEndpoint; +NS_ASSUME_NONNULL_BEGIN + /** * Instances of MIKMIDISequence contain a collection of MIDI tracks. MIKMIDISequences may be thought * of as MIDI "songs". They can be loaded from and saved to MIDI files. They can also be played @@ -41,7 +43,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence, or nil if an error occured. */ -+ (instancetype)sequence; ++ (nullable instancetype)sequence; /** * Creates and initilazes a new instance of MIKMIDISequence from a MIDI file. @@ -52,7 +54,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the loaded file's MIDI sequence, or nil if an error occured. */ -+ (instancetype)sequenceWithFileAtURL:(NSURL *)fileURL error:(NSError **)error; ++ (nullable instancetype)sequenceWithFileAtURL:(NSURL *)fileURL error:(NSError **)error; /** * Creates and initilazes a new instance of MIKMIDISequence from a MIDI file. @@ -66,7 +68,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the loaded file's MIDI sequence, or nil if an error occured. */ -+ (instancetype)sequenceWithFileAtURL:(NSURL *)fileURL convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; ++ (nullable instancetype)sequenceWithFileAtURL:(NSURL *)fileURL convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; /** * Initilazes a new instance of MIKMIDISequence from a MIDI file. @@ -77,7 +79,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the loaded file's MIDI sequence, or nil if an error occured. */ -- (instancetype)initWithFileAtURL:(NSURL *)fileURL error:(NSError **)error; +- (nullable instancetype)initWithFileAtURL:(NSURL *)fileURL error:(NSError **)error; /** * Initilazes a new instance of MIKMIDISequence from a MIDI file. @@ -91,7 +93,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the loaded file's MIDI sequence, or nil if an error occured. */ -- (instancetype)initWithFileAtURL:(NSURL *)fileURL convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; +- (nullable instancetype)initWithFileAtURL:(NSURL *)fileURL convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; /** * Creates and initializes a new instance of MIKMIDISequence from MIDI data. @@ -102,7 +104,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * @return If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, * you may pass in NULL. */ -+ (instancetype)sequenceWithData:(NSData *)data error:(NSError **)error; ++ (nullable instancetype)sequenceWithData:(NSData *)data error:(NSError **)error; /** * Creates and initializes a new instance of MIKMIDISequence from MIDI data. @@ -116,7 +118,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * @return If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, * you may pass in NULL. */ -+ (instancetype)sequenceWithData:(NSData *)data convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; ++ (nullable instancetype)sequenceWithData:(NSData *)data convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; /** * Initializes a new instance of MIKMIDISequence from MIDI data. @@ -127,7 +129,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * @return If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, * you may pass in NULL. */ -- (instancetype)initWithData:(NSData *)data error:(NSError **)error; +- (nullable instancetype)initWithData:(NSData *)data error:(NSError **)error; /** * Initializes a new instance of MIKMIDISequence from MIDI data. @@ -141,7 +143,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * @return If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, * you may pass in NULL. */ -- (instancetype)initWithData:(NSData *)data convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; +- (nullable instancetype)initWithData:(NSData *)data convertMIDIChannelsToTracks:(BOOL)convertMIDIChannelsToTracks error:(NSError **)error; /** * Writes the MIDI sequence in Standard MIDI File format to a file at the specified URL. @@ -157,9 +159,9 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d #pragma mark - Track Management /** - * Creates and adds a new MIDI track to the sequence. + * Creates and adds a new MIDI track to the sequence. May return nil if an error occurs. */ -- (MIKMIDITrack *)addTrack; +- (nullable MIKMIDITrack *)addTrack; /** * Removes the specified MIDI track from the sequence. @@ -271,7 +273,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d /** * The sequencer this sequence is assigned to for playback. */ -@property (nonatomic, readonly) MIKMIDISequencer *sequencer; +@property (nonatomic, readonly, nullable) MIKMIDISequencer *sequencer; /** * The tempo track for the sequence. Even in a new, empty sequence, @@ -311,7 +313,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d /** * The MIDI data that composes the sequence. This data is equivalent to an NSData representation of a standard MIDI file. */ -@property (nonatomic, readonly) NSData *dataValue; +@property (nonatomic, readonly, nullable) NSData *dataValue; /** * A block to be called for each user event added to any music track owned by the sequence. @@ -332,7 +334,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the MIDI data, or nil if an error occured. */ -+ (instancetype)sequenceWithData:(NSData *)data DEPRECATED_ATTRIBUTE; ++ (nullable instancetype)sequenceWithData:(NSData *)data DEPRECATED_ATTRIBUTE; /** * @deprecated This method is deprecated. Use -initWithData:error: instead. @@ -343,7 +345,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @return A new instance of MIKMIDISequence containing the MIDI data, or nil if an error occured. */ -- (instancetype)initWithData:(NSData *)data DEPRECATED_ATTRIBUTE; +- (nullable instancetype)initWithData:(NSData *)data DEPRECATED_ATTRIBUTE; /** * @deprecated This method is deprecated. Use -[MIKMIDISequencer @@ -353,7 +355,7 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d * * @param destinationEndpoint The destination endpoint to set for each track in the sequence. */ -- (void)setDestinationEndpoint:(MIKMIDIDestinationEndpoint *)destinationEndpoint DEPRECATED_ATTRIBUTE; +- (void)setDestinationEndpoint:(nullable MIKMIDIDestinationEndpoint *)destinationEndpoint DEPRECATED_ATTRIBUTE; /** * @deprecated This method has been replaced by -tempoAtTimeStamp: and simply calls through to that method. @@ -393,5 +395,6 @@ NS_INLINE MIKMIDITimeSignature MIKMIDITimeSignatureMake(UInt8 numerator, UInt8 d @end - FOUNDATION_EXPORT const MusicTimeStamp MIKMIDISequenceLongestTrackLength; + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISequence.m b/Source/MIKMIDISequence.m index 09642772..6d7dfaee 100644 --- a/Source/MIKMIDISequence.m +++ b/Source/MIKMIDISequence.m @@ -174,7 +174,7 @@ - (void)dealloc { NSArray *tracks = self.internalTracks; self.internalTracks = nil; // Unregister for KVO - self.callBackBlock = nil; + [self setCallBackBlock:^(MIKMIDITrack *t, MusicTimeStamp ts, const MusicEventUserData *ud, MusicTimeStamp ts2, MusicTimeStamp ts3) {}]; for (MIKMIDITrack *track in tracks) { OSStatus err = MusicSequenceDisposeTrack(_musicSequence, track.musicTrack); @@ -208,7 +208,7 @@ - (MIKMIDITrack *)addTrack [self dispatchSyncToSequencerProcessingQueueAsNeeded:^{ MusicTrack musicTrack; OSStatus err = MusicSequenceNewTrack(self.musicSequence, &musicTrack); - if (err) return NSLog(@"MusicSequenceNewTrack() failed with error %@ in %s.", @(err), __PRETTY_FUNCTION__); + if (err) { NSLog(@"MusicSequenceNewTrack() failed with error %@ in %s.", @(err), __PRETTY_FUNCTION__); }; track = [MIKMIDITrack trackWithSequence:self musicTrack:musicTrack]; [self insertObject:track inInternalTracksAtIndex:[self.internalTracks count]]; @@ -434,7 +434,7 @@ - (NSArray *)tracks tracks = self.internalTracks; }]; - return tracks; + return tracks ?: @[]; } + (NSSet *)keyPathsForValuesAffectingLength diff --git a/Source/MIKMIDISequencer+MIKMIDIPrivate.h b/Source/MIKMIDISequencer+MIKMIDIPrivate.h index f5880b74..4cea3251 100644 --- a/Source/MIKMIDISequencer+MIKMIDIPrivate.h +++ b/Source/MIKMIDISequencer+MIKMIDIPrivate.h @@ -7,10 +7,14 @@ // #import +#import "MIKMIDICompilerCompatibility.h" +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDISequencer (MIKMIDIPrivate) - (void)dispatchSyncToProcessingQueueAsNeeded:(void (^)())block; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISequencer.h b/Source/MIKMIDISequencer.h index 81143e81..ff150551 100644 --- a/Source/MIKMIDISequencer.h +++ b/Source/MIKMIDISequencer.h @@ -8,6 +8,7 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDISequence; @class MIKMIDITrack; @@ -34,6 +35,7 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { MIKMIDISequencerClickTrackStatusAlwaysEnabled }; +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDISequencer can be used to play and record to an MIKMIDISequence. @@ -205,10 +207,10 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { * @note If track is not contained by the receiver's sequence, this method does nothing. * * @param commandScheduler An object that conforms to MIKMIDICommandScheduler with which events - * in track should be scheduled during playback. + * in track should be scheduled during playback. Pass nil to remove an existing command scheduler * @param track An MIKMIDITrack instance. */ -- (void)setCommandScheduler:(id)commandScheduler forTrack:(MIKMIDITrack *)track; +- (void)setCommandScheduler:(nullable id)commandScheduler forTrack:(MIKMIDITrack *)track; /** * Returns the command scheduler for a track in the sequencer's sequence. @@ -228,7 +230,7 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { * @see -builtinSynthesizerForTrack: * @see createSynthsIfNeeded */ -- (id)commandSchedulerForTrack:(MIKMIDITrack *)track; +- (nullable id)commandSchedulerForTrack:(MIKMIDITrack *)track; /** * Returns synthesizer the receiver will use to synthesize MIDI during playback @@ -243,14 +245,14 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { * * @return An MIKMIDISynthesizer instance, or nil if a builtin synthesizer for track doesn't exist. */ -- (MIKMIDISynthesizer *)builtinSynthesizerForTrack:(MIKMIDITrack *)track; +- (nullable MIKMIDISynthesizer *)builtinSynthesizerForTrack:(MIKMIDITrack *)track; #pragma mark - Properties /** * The sequence to playback and record to. */ -@property (strong, nonatomic) MIKMIDISequence *sequence; +@property (nonatomic, strong) MIKMIDISequence *sequence; /** * Whether or not the sequencer is currently playing. This can be observed with KVO. @@ -371,7 +373,7 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { /** * The metronome to send click track events to. */ -@property (strong, nonatomic) MIKMIDIMetronome *metronome; +@property (nonatomic, strong, nullable) MIKMIDIMetronome *metronome; /** * When the click track should be heard. @@ -387,20 +389,20 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { * @see recording * */ -@property (copy, nonatomic) NSSet *recordEnabledTracks; +@property (nonatomic, copy, nullable) NSSet *recordEnabledTracks; /** * An MIKMIDIClock that is synced with the sequencer's internal clock. * * @ @see -[MIKMIDIClock syncedClock] */ -@property (readonly, nonatomic) MIKMIDIClock *syncedClock; +@property (nonatomic, readonly) MIKMIDIClock *syncedClock; /** * The latest MIDITimeStamp the sequencer has looked ahead to to schedule MIDI events. */ -@property (readonly, nonatomic) MIDITimeStamp latestScheduledMIDITimeStamp; +@property (nonatomic, readonly) MIDITimeStamp latestScheduledMIDITimeStamp; #pragma mark - Deprecated @@ -438,7 +440,7 @@ typedef NS_ENUM(NSInteger, MIKMIDISequencerClickTrackStatus) { * @see -builtinSynthesizerForTrack: * @see createSynthsAndEndpointsIfNeeded */ -- (MIKMIDIDestinationEndpoint *)destinationEndpointForTrack:(MIKMIDITrack *)track __attribute((deprecated("use -setCommandScheduler:forTrack: instead"))); +- (nullable MIKMIDIDestinationEndpoint *)destinationEndpointForTrack:(MIKMIDITrack *)track __attribute((deprecated("use -setCommandScheduler:forTrack: instead"))); @end @@ -453,3 +455,5 @@ FOUNDATION_EXPORT NSString * const MIKMIDISequencerWillLoopNotification; * sequence regardless of sequence length. */ FOUNDATION_EXPORT const MusicTimeStamp MIKMIDISequencerEndOfSequenceLoopEndTimeStamp; + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISequencer.m b/Source/MIKMIDISequencer.m index 67e9d00a..a74557dd 100644 --- a/Source/MIKMIDISequencer.m +++ b/Source/MIKMIDISequencer.m @@ -137,7 +137,7 @@ + (instancetype)sequencer - (void)dealloc { - self.sequence = nil; // remove KVO + [_sequence removeObserver:self forKeyPath:@"tracks"]; self.processingTimer = NULL; } @@ -552,6 +552,10 @@ - (MIKMIDINoteEvent *)pendingNoteEventWithNoteNumber:(NSNumber *)noteNumber chan - (void)setCommandScheduler:(id)commandScheduler forTrack:(MIKMIDITrack *)track { + if (!commandScheduler) { + [self.tracksToDestinationsMap removeObjectForKey:track]; + return; + } [self.tracksToDestinationsMap setObject:commandScheduler forKey:track]; [self.tracksToDefaultSynthsMap removeObjectForKey:track]; } diff --git a/Source/MIKMIDISourceEndpoint.h b/Source/MIKMIDISourceEndpoint.h index cdb8a804..5a09251a 100644 --- a/Source/MIKMIDISourceEndpoint.h +++ b/Source/MIKMIDISourceEndpoint.h @@ -7,6 +7,9 @@ // #import "MIKMIDIEndpoint.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDISourceEndpoint represents a source (input) MIDI endpoint. @@ -26,3 +29,5 @@ @interface MIKMIDISourceEndpoint : MIKMIDIEndpoint @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISynthesizer.h b/Source/MIKMIDISynthesizer.h index 9cdb4716..950fa537 100644 --- a/Source/MIKMIDISynthesizer.h +++ b/Source/MIKMIDISynthesizer.h @@ -10,6 +10,9 @@ #import #import "MIKMIDISynthesizerInstrument.h" #import "MIKMIDICommandScheduler.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDISynthesizer provides a simple way to synthesize MIDI messages to @@ -35,7 +38,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)init; +- (nullable instancetype)init; /** * Initializes an MIKMIDISynthesizer instance which uses an audio unit matching @@ -46,7 +49,7 @@ * * @return An initialized MIKMIDIEndpointSynthesizer or nil if an error occurs. */ -- (instancetype)initWithAudioUnitDescription:(AudioComponentDescription)componentDescription NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithAudioUnitDescription:(AudioComponentDescription)componentDescription NS_DESIGNATED_INITIALIZER; /** * This synthesizer's available instruments. An array of @@ -128,7 +131,7 @@ * * @see -setupAUGraph */ -@property (nonatomic, readonly) AudioUnit instrumentUnit; +@property (nonatomic, readonly, nullable) AudioUnit instrumentUnit; /** * The AUGraph for the instrument. @@ -138,7 +141,7 @@ * * @see -setupAUGraph */ -@property (nonatomic) AUGraph graph; +@property (nonatomic, nullable) AUGraph graph; // Deprecated @@ -148,3 +151,5 @@ @property (nonatomic) AudioUnit instrument DEPRECATED_ATTRIBUTE; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISynthesizer.m b/Source/MIKMIDISynthesizer.m index 8a2ec338..c784fcc9 100644 --- a/Source/MIKMIDISynthesizer.m +++ b/Source/MIKMIDISynthesizer.m @@ -98,7 +98,7 @@ - (NSArray *)availableInstruments OSStatus err = AudioUnitGetProperty(audioUnit, kMusicDeviceProperty_InstrumentName, kAudioUnitScope_Global, instrumentID, &cName, &cNameSize); if (err) { NSLog(@"AudioUnitGetProperty() failed with error %@ in %s.", @(err), __PRETTY_FUNCTION__); - return nil; + return @[]; } NSString *name = [NSString stringWithCString:cName encoding:NSASCIIStringEncoding]; diff --git a/Source/MIKMIDISynthesizerInstrument.h b/Source/MIKMIDISynthesizerInstrument.h index dd9abb51..216f4b8e 100644 --- a/Source/MIKMIDISynthesizerInstrument.h +++ b/Source/MIKMIDISynthesizerInstrument.h @@ -8,6 +8,9 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * MIKMIDISynthesizerInstrument is used to represent @@ -22,7 +25,7 @@ * * @return A MIKMIDISynthesizerInstrument instance with the matching instrument ID, or nil if no instrument was found. */ -+ (instancetype)instrumentWithID:(MusicDeviceInstrumentID)instrumentID name:(NSString *)name; ++ (nullable instancetype)instrumentWithID:(MusicDeviceInstrumentID)instrumentID name:(NSString *)name; /** * The human readable name of the receiver. e.g. "Piano 1". @@ -60,6 +63,8 @@ * * @return A MIKMIDISynthesizerInstrument with the matching instrument ID, or nil if no instrument was found. */ -+ (instancetype)instrumentWithID:(MusicDeviceInstrumentID)instrumentID DEPRECATED_ATTRIBUTE; ++ (nullable instancetype)instrumentWithID:(MusicDeviceInstrumentID)instrumentID DEPRECATED_ATTRIBUTE; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISynthesizerInstrument.m b/Source/MIKMIDISynthesizerInstrument.m index 0d5b2aca..b400ad39 100644 --- a/Source/MIKMIDISynthesizerInstrument.m +++ b/Source/MIKMIDISynthesizerInstrument.m @@ -19,7 +19,7 @@ - (instancetype)initWithName:(NSString *)name instrumentID:(MusicDeviceInstrumen { self = [super init]; if (self) { - _name = name; + _name = name ?: @"No instrument name"; _instrumentID = instrumentID; } return self; @@ -108,12 +108,12 @@ + (NSArray *)availableInstruments availableInstruments = [result copy]; }); - return availableInstruments; + return availableInstruments ?: @[]; } + (instancetype)instrumentWithID:(MusicDeviceInstrumentID)instrumentID { - return [self instrumentWithID:instrumentID name:nil]; + return [self instrumentWithID:instrumentID name:@"Unspecified Name"]; } @end \ No newline at end of file diff --git a/Source/MIKMIDISynthesizer_SubclassMethods.h b/Source/MIKMIDISynthesizer_SubclassMethods.h index 6072a875..20990cc5 100644 --- a/Source/MIKMIDISynthesizer_SubclassMethods.h +++ b/Source/MIKMIDISynthesizer_SubclassMethods.h @@ -7,11 +7,16 @@ // #import "MIKMIDISynthesizer.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDISynthesizer () - (BOOL)sendBankSelectAndProgramChangeForInstrumentID:(MusicDeviceInstrumentID)instrumentID error:(NSError **)error; -@property (nonatomic, readwrite) AudioUnit instrumentUnit; +@property (nonatomic, readwrite, nullable) AudioUnit instrumentUnit; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISystemExclusiveCommand.h b/Source/MIKMIDISystemExclusiveCommand.h index 09ccaa96..7e6e28d4 100644 --- a/Source/MIKMIDISystemExclusiveCommand.h +++ b/Source/MIKMIDISystemExclusiveCommand.h @@ -7,6 +7,7 @@ // #import "MIKMIDISystemMessageCommand.h" +#import "MIKMIDICompilerCompatibility.h" #define kMIKMIDISysexNonRealtimeManufacturerID 0x7E #define kMIKMIDISysexRealtimeManufacturerID 0x7F @@ -14,6 +15,8 @@ #define kMIKMIDISysexChannelDisregard 0x7F #define kMIKMIDISysexEndDelimiter 0xF7 +NS_ASSUME_NONNULL_BEGIN + /** * A MIDI System Exclusive (SysEx) message. System exclusive messages are * messages defined by individual manufacturers of MIDI devices. They @@ -84,6 +87,8 @@ @property (nonatomic, readwrite) UInt8 dataByte2; @property (nonatomic, readwrite) MIDITimeStamp midiTimestamp; -@property (nonatomic, copy, readwrite) NSData *data; +@property (nonatomic, copy, readwrite, null_resettable) NSData *data; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDISystemMessageCommand.h b/Source/MIKMIDISystemMessageCommand.h index d3461512..7a537b84 100644 --- a/Source/MIKMIDISystemMessageCommand.h +++ b/Source/MIKMIDISystemMessageCommand.h @@ -7,6 +7,9 @@ // #import "MIKMIDICommand.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI system message command. This class is also the base class for @@ -27,6 +30,8 @@ @property (nonatomic, readwrite) UInt8 dataByte2; @property (nonatomic, readwrite) MIDITimeStamp midiTimestamp; -@property (nonatomic, copy, readwrite) NSData *data; +@property (nonatomic, copy, readwrite, null_resettable) NSData *data; + +@end -@end \ No newline at end of file +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDITempoEvent.h b/Source/MIKMIDITempoEvent.h index d859a11d..61d23e8b 100644 --- a/Source/MIKMIDITempoEvent.h +++ b/Source/MIKMIDITempoEvent.h @@ -7,6 +7,9 @@ // #import "MIKMIDIEvent.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN /** * A MIDI tempo event. @@ -22,7 +25,7 @@ * * @return A new instance of MIKMIDITempoEvent, or nil if an error occured. */ -+ (instancetype)tempoEventWithTimeStamp:(MusicTimeStamp)timeStamp tempo:(Float64)bpm; ++ (nullable instancetype)tempoEventWithTimeStamp:(MusicTimeStamp)timeStamp tempo:(Float64)bpm; /** * The beats per minute of the tempo event. @@ -37,7 +40,9 @@ @interface MIKMutableMIDITempoEvent : MIKMIDITempoEvent @property (nonatomic, readwrite) MusicTimeStamp timeStamp; -@property (nonatomic, strong, readwrite) NSMutableData *data; +@property (nonatomic, strong, readwrite, null_resettable) NSMutableData *data; @property (nonatomic, readwrite) Float64 bpm; -@end \ No newline at end of file +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDITrack.h b/Source/MIKMIDITrack.h index 49310fca..6be539f2 100644 --- a/Source/MIKMIDITrack.h +++ b/Source/MIKMIDITrack.h @@ -8,12 +8,15 @@ #import #import +#import "MIKMIDICompilerCompatibility.h" @class MIKMIDISequence; @class MIKMIDIEvent; @class MIKMIDINoteEvent; @class MIKMIDIDestinationEndpoint; +NS_ASSUME_NONNULL_BEGIN + /** * Instances of MIKMIDITrack contain sequences of MIDI events. Commonly, * these will be MIDI notes. Multiple MIKMIDITracks can be contained in a @@ -153,7 +156,7 @@ /** * The MIDI sequence the track belongs to. */ -@property (weak, nonatomic, readonly) MIKMIDISequence *sequence; +@property (weak, nonatomic, readonly, nullable) MIKMIDISequence *sequence; /** * The underlying MusicTrack that backs the instance of MIKMIDITrack. @@ -274,7 +277,7 @@ * * The destination endpoint for the MIDI events of the track during playback. */ -@property (nonatomic, strong, readwrite) MIKMIDIDestinationEndpoint *destinationEndpoint DEPRECATED_ATTRIBUTE; +@property (nonatomic, strong, readwrite, nullable) MIKMIDIDestinationEndpoint *destinationEndpoint DEPRECATED_ATTRIBUTE; /** * @deprecated Use -addEvent: instead. @@ -319,3 +322,5 @@ - (BOOL)clearAllEvents DEPRECATED_ATTRIBUTE; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/MIKMIDITrack.m b/Source/MIKMIDITrack.m index 0c0f9ad6..3c6e40cb 100644 --- a/Source/MIKMIDITrack.m +++ b/Source/MIKMIDITrack.m @@ -23,7 +23,7 @@ @interface MIKMIDITrack () -@property (weak, nonatomic) MIKMIDISequence *sequence; +@property (weak, nonatomic, nullable) MIKMIDISequence *sequence; @property (nonatomic, strong) NSMutableSet *internalEvents; @property (nonatomic, strong) NSArray *sortedEventsCache; @@ -321,12 +321,12 @@ - (NSArray *)eventsOfClass:(Class)eventClass fromTimeStamp:(MusicTimeStamp)start events = mutableEvents; }]; - return events; + return events ?: @[]; } - (NSArray *)eventsFromTimeStamp:(MusicTimeStamp)startTimeStamp toTimeStamp:(MusicTimeStamp)endTimeStamp { - return [self eventsOfClass:Nil fromTimeStamp:startTimeStamp toTimeStamp:endTimeStamp]; + return [self eventsOfClass:[MIKMIDIEvent class] fromTimeStamp:startTimeStamp toTimeStamp:endTimeStamp]; } - (NSArray *)notesFromTimeStamp:(MusicTimeStamp)startTimeStamp toTimeStamp:(MusicTimeStamp)endTimeStamp @@ -538,7 +538,7 @@ - (NSArray *)events events = self.sortedEventsCache; }]; - return events; + return events ?: @[]; } - (void)setEvents:(NSArray *)events diff --git a/Source/MIKMIDITrack_Protected.h b/Source/MIKMIDITrack_Protected.h index 68755f98..6bbeff4a 100644 --- a/Source/MIKMIDITrack_Protected.h +++ b/Source/MIKMIDITrack_Protected.h @@ -7,6 +7,9 @@ // #import "MIKMIDITrack.h" +#import "MIKMIDICompilerCompatibility.h" + +NS_ASSUME_NONNULL_BEGIN @interface MIKMIDITrack () @@ -19,7 +22,7 @@ * @note You should not call this method. It is for internal MIKMIDI use only. * To add a new track to a MIDI sequence use -[MIKMIDISequence addTrack]. */ -+ (instancetype)trackWithSequence:(MIKMIDISequence *)sequence musicTrack:(MusicTrack)musicTrack; ++ (nullable instancetype)trackWithSequence:(MIKMIDISequence *)sequence musicTrack:(MusicTrack)musicTrack; /** * Sets a temporary length and loopInfo for the track. @@ -39,3 +42,5 @@ - (void)restoreLengthAndLoopInfo; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/Source/NSUIApplication+MIKMIDI.h b/Source/NSUIApplication+MIKMIDI.h index 8e3a3d1a..58bf9513 100644 --- a/Source/NSUIApplication+MIKMIDI.h +++ b/Source/NSUIApplication+MIKMIDI.h @@ -24,6 +24,8 @@ #endif +#import "MIKMIDICompilerCompatibility.h" + /** * Define MIKMIDI_SEARCH_VIEW_HIERARCHY_FOR_RESPONDERS as a non-zero value to (re)enable searching * the view hierarchy for MIDI responders. This is disabled by default because it's slow. @@ -36,6 +38,8 @@ @class MIKMIDICommand; +NS_ASSUME_NONNULL_BEGIN + /** * MIKMIDI implements a category on NSApplication (on OS X) or UIApplication (on iOS) * to facilitate the creation and use of a MIDI responder hierarchy, along with the ability @@ -108,7 +112,7 @@ * @return An object that conforms to MIKMIDIResponder, or nil if no registered responder for the passed in identifier * could be found. */ -- (id)MIDIResponderWithIdentifier:(NSString *)identifier; +- (nullable id)MIDIResponderWithIdentifier:(NSString *)identifier; /** * Returns all MIDI responders that have been registered with the application. @@ -135,3 +139,5 @@ @property (nonatomic) BOOL shouldCacheMIKMIDISubresponders; @end + +NS_ASSUME_NONNULL_END \ No newline at end of file