NS_DESIGNATED_INITIALIZER expected : (colon) - objective-c

I am trying to declare a designated initializer like this:
- (instancetype)initWithDelegate:(id <MyDelegate>)delegate NS_DESIGNATED_INITIALIZER;
But it is showing me this compilation error:
Expected ':'
Interestingly when I try to write it like this (reference link: Adopting Modern Objective-C) -
- (instancetype)init NS_DESIGNATED_INITIALIZER;
It shows this error:
Expected ';' after method prototype.
Any ideas on how to properly use NS_DESIGNATED_INITIALIZER?

NS_DESIGNATED_INITIALIZER macro is not defined in the library headers for Xcode 5 - you need Xcode 6 to use it. Note your link says "Pre-release".
The macro is defined in the following way (quoting NSObjCRuntime.h)
#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
#else
#define NS_DESIGNATED_INITIALIZER
#endif
#endif
Note you can still use
- (instancetype)initWithDelegate:(id <MyDelegate>)delegate __attribute__((objc_designated_initializer));
in Xcode 5 or you can add that macro explicitly to your precompiled header.

Bear in mind you can only add this to interface or class extension declarations otherwise you'll get this error:
'objc_designated_initializer' attribute only applies to init methods of interface or class extension declarations

Related

Lint error objectiveC

I have a linting error on my objC but I don't know how to resolve it, if I'm using the reinterpret_cast syntax, the app does not build anymore... Someone has an idea please?
error: NSString+EXT.h:9: Using C-style cast. Use reinterpret_cast(...) instead [readability/casting]
NSString+EXT.h
#ifndef ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
#define ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
#import <Foundation/Foundation.h>
#interface NSString(ANSI)
- (BOOL)containsANSICodes;
- (NSMutableAttributedString*)attributedStringParsingANSICodes;
#end
#endif // ATOM_BROWSER_UI_COCOA_NSSTRING_ANSI_H_
After multiple research and test, I fix the issue by following this thread
A macro like
#define REINTERPRET(type, expr) (*(type *)&(expr))
help me to refactorize and resolve the issue

project-Swift.h compiler errors

Im having an issue with the auto-generated Project-Swift.h file when I try to import it.
In the -Swift.h file:
SWIFT_CLASS("_TtC7ProjectName20InviteToComposer")
#interface InviteToComposer : NSObject <MFMessageComposeViewControllerDelegate *>
- (nonnull instancetype)initWithRecipient:(NSArray<NSString *> * _Nonnull)recipient name:(NSString * _Nonnull)name OBJC_DESIGNATED_INITIALIZER;
- (void)messageComposeViewController:(MFMessageComposeViewController * _Nonnull)controller didFinishWithResult:(MessageComposeResult)result;
#end
when attempting to compile, i get two errors from this class:
"unknown type name 'MFMessageComposeViewControllerDelegate'; did you mean 'MFMessageComposeViewController'?
and "expected a type" in regards to "(MessageComposeResult)"
I tried including #nonobjc in front of the class and function names so that it wouldn't include them in the -Swift.h file, but apparently you can't do that to a class and the function itself that has the error gives me
"Type 'InviteToComposer' does not conform to protocol 'MFMessageComposeViewControllerDelegate'" then states "protocol is not #objc but requires it."
In your -swift add #protocol MFMessageComposeViewControllerDelegate before your class declaration.
It's an apple "you probably should be using swift/we don't care enough about you to fix it" thing.
Also thing with my fix is that every time you clean the project or switch a build device, it will clear up the code and you have to add it again.
A permeant workaround is create a sub protocol of the MFMessageComposeViewControllerDelegate in objective-c and reference it from there.

Use of unresolved identifier 'PKCS7_type_is_signed'

I'm writing the receipt validation code in swift, but I have a problem with a PKCS7_type_is_signed macro :
Use of unresolved identifier 'PKCS7_type_is_signed'
Are there any way to use it in Swift except of creating Objective-C wrapper for this macros ?
Wrapper looks like this :
#import "OpenSSLWrapper.h"
#import "openssl/pkcs7.h"
#import "openssl/objects.h"
#implementation OpenSSLWrapper
+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
return PKCS7_type_is_signed(bio);
}
#end
The macro won't work in Swift. You must write a wrapper.
Swift cannot discern type information from a macro. What sort of arguments should the Swift compiler allow to be passed into that macro? Because it cannot discern, it will not compile it.
It's also probably worth mentioning that in C/Objective-C, these macros are simple find & replace. The macro is expanded before compilation. If this macro did expand, it'd almost certainly expand into code that wouldn't compile in a .swift file.
From Apples
Using Swift with Cocoa and Objective-C
Complex macros are used in C and Objective-C but have no counterpart
in Swift. Complex macros are macros that do not define constants,
including parenthesized, function-like macros. You use complex macros
in C and Objective-C to avoid type-checking constraints or to avoid
retyping large amounts of boilerplate code. However, macros can make
debugging and refactoring difficult. In Swift, you can use functions
and generics to achieve the same results without any compromises.
Therefore, the complex macros that are in C and Objective-C source
files are not made available to your Swift code.
And as pointed by nhgrif (thank you :-) ), 2 options here use wrapper or just expand macro.
Expand Macro :
# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
func PKCS7_type_is_signed(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
return OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_signed
}
func PKCS7_type_is_data(pkcs:UnsafeMutablePointer<PKCS7>)->Bool{
return (OBJ_obj2nid(pkcs.memory.type) == NID_pkcs7_data)
}
Wrapper :
.h file:
#import <Foundation/Foundation.h>
#import "openssl/pkcs7.h"
#import "openssl/objects.h"
#interface OpenSSLWrapper:NSObject
+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio;
+ (BOOL)PKCS7TypeIsData:(PKCS7*)contents;
#end
.m file :
#import "OpenSSLWrapper.h"
#implementation OpenSSLWrapper
+ (BOOL)PKCS7TypeIsSigned:(PKCS7*)bio{
return PKCS7_type_is_signed(bio);
}
+ (BOOL)PKCS7TypeIsData:(PKCS7*)contents{
return PKCS7_type_is_data(contents);
}
#end

I am having all the time this issue after running my app

I don't know why, but after a while working without problems I added some buttons, then I launched my app and this error appeared:
ld: duplicate symbol _x in
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/SeconViewController.o
and
/Users/alexbarco/Library/Developer/Xcode/DerivedData/RecolectaDatos-ayjpqqcajbhuzvbkvernzsyunpbe/Build/Intermediates/RecolectaDatos.build/Debug-iphonesimulator/RecolectaDatos.build/Objects-normal/i386/ViewController.o
for architecture i386 clang: error: linker command failed with exit
code 1 (use -v to see invocation)
Whenever I have duplicate symbol errors, it is almost always because I have a circular #import in my headers. The solution is quite simple, use forward declarations where possible, and #import .h files from .m files instead.
There are just two cases where you need to #import one .h from another:
if you are extending the class in the #import
you are implementing a protocol in the #import
Specifically, you do not need to import files just to use a class name or protocol in your signatures; instead use forward declarations.
For example, this (in Bar.h):
#import "Foo.h"
might become this (Bar.h):
#class Foo;
#protocol FooDelegate;
and bar.m:
#import "Foo.h"
Here is a link to the documentation on forward declarations.
The "duplicate symbol" message means that you're declaring some name (in this case, _x) twice in the same scope. Say you had code like this:
int _x = 1;
int _x = 2;
You'd expect to get an error then, right? You can use the same name for two things at the same time.
The error you're getting is essentially the same. You're declaring _x somewhere, and from the compiler's point of view you're doing it twice. There are a few ways to deal with this, depending on what _x represents.
chrahey's answer explains about forward class declarations. I won't cover that again here except to say that a forward declaration helps you resolve circular references, where the definition of class A depends on class B and vice versa.
If _x is a variable, it's likely that you're trying to declare it in a header file. The compiler basically copies the contents of each header file that you import into the source file, so if you declare a variable in a header file and then import that header into two or more implementation files, you'll end up with multiple declarations of that variable. To get around that, use the extern keyword to tell the compiler "this name will be declared somewhere else" and then put the real declaration in an implementation file:
Foo.h:
extern int _x;
Foo.m
int _x;
Pretty much the same thing goes for functions. It doesn't appear that _x is a function, but if it were, and if you were silly enough to put the function definition in a header file, then you'd again get an error if that file were imported into more than one implementation file. This is why header files contain prototypes, not definitions:
Foo.h:
int foo(int a);
Foo.m
int foo(int a)
{
return a + 10;
}

Newbie question -multiple parameters

I am trying to implement a private method which takes an NSMutableDictionary and a Player object as its parameters. As it is a private method, the only place that it exists is in the ".m" file.
It is declared as
-(void) incrementScore: (NSMutableDictionary*) scoreboard forPlayer: ( Player* ) player {
and I call it as follows :
[ self incrementScore:deuceScore forPlayer:p];
However,it won't compile - I get
may not response to message -incrementScore:forplayer
I'm not sure where my error lies - do I need to declare the method in the ".h" file, or elsewhere in the ".m" file, or have I just got the syntax completely wrong?
The compiler needs to find a declaration for your method somewhere before you use it. This be done in three way:
Declare the method in the (public) #interface for the class in its .h file .
Declare the method in a class extension (a semi-private #interface, usually at the top of the .m files).
Define the method somewhere in the #implementation before your first use of it.
This is only a warning not a compile error... (if you changed preferences to treat all warnings like error it'll be a compile error).
Probably the line calling the method is above (in the .m file) the declaration method. Move the method just below #implementation directive, or above the method with the calling line. The warning/error should disapper.