I am coding a speedcubing timer and I am trying to get the tnoodle-lib library (link here) working with my Xcode project. So far I have managed to import everything I think, but I don't know how to actually generate the scrambles with it. Can somebody please help?
Here is what I have going on:
in my Header.h bridging file:
#ifndef Bridging_Header_h
#define Bridging_Header_h
#import "org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.h"
#import "org/worldcubeassociation/tnoodle/scrambles/Puzzle.h"
#import "org/worldcubeassociation/tnoodle/svglite/Svg.h"
#import "org/worldcubeassociation/tnoodle/svglite/Dimension.h"
NSString * const SCRAMBLE = "/("NSSOrgWorldcubeassociationTnoodleScramblesPuzzleRegistry_get_THREE())"
#endif /* Bridging_Header_h */
In my project build settings I imported the tnoodle-lib-objc stuff like it said on the github page. What I can't figure out is how to actually use this to generate scrambles because it seems like you would do that in java, and I don't know how to transfer it from java to swift.
I think it's good to understand what the bridging header does. As we're using Objective-C code, we need to "bridge" this code so it can be used in Swift – this is the purpose of the bridging header. It should only act as an intermediate for the Objective-C code we need, which are the import statements.
Your bridging header should look something like this, for a very simple bare bones approach:
#ifndef Bridging_Header_h
#define Bridging_Header_h
#import "org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.h"
#import "org/worldcubeassociation/tnoodle/scrambles/Puzzle.h"
#endif
This gives us access to the tnoodle Puzzle and PuzzleRegistry components.
From here, in our Swift code – anywhere in your main program, you should be able to call the scrambler. For example:
OrgWorldcubeassociationTnoodleScramblesPuzzleRegistry.TWO.getScrambler().generateScramble()
.TWO is the scramble type, could be .THREE, SQ1, any tnoodle scramble type. If you refer to the tnoodle repo, you can see how they've defined their Puzzle, with methods.
Each "puzzle type" has a .getScrambler() method, which returns an OrgWorldcubeassociationTnoodleScramblesPuzzle object, where .generateScramble() can then be called. This will generate a scramble for for the puzzle type you've chosen.
Be wary that the returned object is an Optional, you will need to unwrap to obtain the String.
Related
I converted my app long ago from Obj-C to Swift. During conversion, I needed a Bridging-Header file.
Now I realized that this file is still defined for one target, although the project uses now only Swift files.
Thus I thought I can simply delete Target/Build Settings/Objective-C Bridging Header.
However, the project then no longer builds.
The bridging header file contains (for historical reasons, since I used earlier the Obj-C version of the StoreKit, but no longer) only a single entry:
#import <StoreKit/StoreKit.h>
If this entry is out commented, I get the error
Cannot find 'UIApplicationMain' in scope
in my main file that contains essentially only
let appDelegateClassName: String?
if !ProcessInfo.processInfo.isTesting {
// No unit test. Use the normal app delegate.
appDelegateClassName = NSStringFromClass(AppDelegate.self)
} else {
// Unit test. No app delegate is used.
appDelegateClassName = nil
}
let args = UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc))
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, appDelegateClassName)
I assume, I don't need a Bridging-Header, if I don't have any Obj-C files. So why do I get this error when I simply out comment #import <StoreKit/StoreKit.h>? And how do I get rid of all old Obj-C traces?
UIApplicationMain is defined in the UIKit framework, so you need to add
import UIKit
to the main.swift file. With
#import <StoreKit/StoreKit.h>
in the bridging header file it happens to compile because StoreKit.h includes SKOverlay.h, which in turn includes UIKit.h (when compiled for iOS).
I am reading about iOS programming and I bought the Programming iOS 4 book. There is a introductory part where among several things "Files" is mentioned.
I don't understand how the source files is put together. You have a header file with function declarations, then you have a corresponding file with the function definitions.
Let say you have a Car.h and Car.m & Person.h and Person.m.
Now, if you want to use the Car in the Person class you would import only the Car.h file. How is this sufficient? I don't understand the sequence it put together and builds a program. (Not thinking about the technical stuff, just h/m files.)
The .h or "header file" contains the interface.
The .m or "implementation file" contains the implementation.
Each implementation file is also called a "compilation unit" because the compiler compiles each one separately. Within each compilation unit, the compiler needs to know about types and methods. All it needs to know about a class to create the right code is information about the methods it implements.
So let's imagine you have these files:
Car.h
#import <Foundation/Foundation.h>
#interface Car : NSObject
- (void)drive;
#end
Car.m
#import "Car.h"
#implementation Car
- (void)drive {
NSLog(#"I'm driving!");
}
#end
Person.h
#import <Foundation/Foundation.h>
#class Car;
#interface Person : NSObject
#property (nonatomic, strong) Car *car;
- (void)start;
#end
Person.m
#import "Person.h"
#import "Car.h"
#implementation Person
#synthesize car;
- (void)start {
[car drive];
}
#end
Now when the compiler does its business, it compiles both Car.m and Person.m into Car.o and Person.o respectively. [These then get linked into the final binary, but that's beyond the scope of this question for now].
When it compiles Person.m, the compiler doesn't need to know how - (void)drive of Car is implemented, but it does need to know that it exists, that it is a method that takes no arguments and returns nothing. It doesn't care about the implementation, just that it exists. So you just need to #import the header file of Car to tell the compiler about the methods that exist on Car. The compiler knows that the implementation exists, because you've told it so, and then later on the linker will do it's business to correctly wire up the method call to the correct implementation. How the linker actually does that is a huge topic and I encourage you to go and read about it separately if you don't already understand it.
Note that it's the same for all of the standard NS classes that you use such as NSObject, NSString, etc. You just need to #import Foundation.h from the Foundation framework which tells the compiler about what these classes are and what methods are defined on them.
Creating an executable from a set of source code files is a two stage process.
Firstly, all of the .m files are individually compiled with the Objective-C compiler. This turns each one into a .o file which is an object code file. However, if the code in a .m file refers to things that are defined in other .m files, the compiler does not know about these so it just leaves unresolved references in the .o file.
The second stage is called linking. This takes all the .o files and combines them into an executable. When the linker finds unresolved references in one .o file, it checks all the others to resolve the reference.
Header files allow the compiler to have some information from outside the particular .m file it is currently compiling. So if you have two classes Foo and Bar they are conventionally defined in files Foo.m and Bar.m In order for the compiler to know what class Bar looks like when it is compiling Foo.m we put class Bars interface declaration in a header file (conventionally Bar.h) and import it into your .m file. If you see the line
#import "Bar.h"
it is literally as if the compiler has copy-pasted the entire header file into the source code file before compiling it.
What language have you been using until now? Many languages do it this way including c and c++. The m files are compiled into an actual program, and the h files provide a list of ways to interact with it. While you can still call the methods if you interact with the objective c runtime, the compiler will not guarantee their existence unless they are in the h file.
Now, I say guarantee, but if you dont provide an implementation in the m file, the sibling to the compiler, the linker will have a fit. It will try to make a jump into another m file based on its h file only to tragically discover that it is not there.
The benefits of splitting like this is that you can compile your source into a library and distribute it along with the h files and another application can use it without having the implementation source code.
In summary the m files compile into a lost island of bits and the h files are the map to get around it. If something is on the map that doesnt exist then you will get lost. If something exists but is not on the map then you will have a lot of trouble finding it.
Header files specify what messages ("methods" in other languages) can be passed to a class. That's all the compiler needs to know to compile your code; the linker will eventually wire everything up, so to speak, using the *.m files.
The compiler will handle that for you.
As you stated, a header file contains just the declarations.
Its like a interface to the actual code and that is the only thing Compiler needs to know to fetch the rest.
I am new in iphone development and i have little bit Question.
My Question is When do we use #class and #import in .h (header )file.And if your answer is #class u can create instance but can not.. use its methods and by use of #import in .h file we can access all method and variable of second class .Then My Question is
if #import contains advantage then why many people used only #class in their .h file.
Please anybody have answer then reply asap.Thanks in Advance.
First of all, you're right with your assumption.
As for advantages:
The #class directive is faster, since it only discloses the Name, and the Inheritance to the Namespace (e.g. the Header File). But #import loads everything, so it's slower and means more load on the system. If your Code is a library for another system, its pretty useful if the headerfiles only load the classname (#class)
For an example. You have the class A, and are importing a Headerfile B from a library. B itself wants to use C. If it imports all data in the B Headerfile, it gets bloated, because you would load it too when importing the headerfile into your class A. But it isn't necessary, that your class A knows what Class C is capable of, because only B is using it.
Have you ever encountered cyclic imports,I suppose you are not.
The other answers are also correct but when it comes to cyclic imports the compiler gives error and you have to use #class instead of import.
quick example
//A.h
#import "B.h"
//B.h
#import "A.h"
In this case compiler will give you the error. So you have to use #class in one of the header files to remove cyclic import. It is true that #class is faster than #import but my projects doesn't have large amount of files that it would take hours to compile it :)
OK, trying to be more clear, then. This is what you usually want:
Use #class in your .h file if the header file doesn't need access to anything in the class you're importing (i.e. it only needs to know that the class exists in order to compile).
Use #import in your .m file to get access to the imported class' properties and methods.
An example, where your class Foo needs to use another class you've created, Bar. Bar also has a custom initializer, -initWithCustomValue:.
MyClass.h
#class Bar
...
Bar _instanceVariable;
MyClass.m
#import "Bar.h"
...
_instanceVariable = [[Bar alloc] initWithCustomValue:1];
This would make sure that you're not exposing unnecessary code (i.e. the contents of Bar) to other classes that might be importing MyClass.h.
From the Apple docs:
The #class directive minimizes the amount of code seen by the compiler
and linker, and is therefore the simplest way to give a forward
declaration of a class name. Being simple, it avoids potential
problems that may come with importing files that import still other
files. For example, if one class declares a statically typed instance
variable of another class, and their two interface files import each
other, neither class may compile correctly.
I have a class method but when in header file, it doesn´t want to compile:"expected a type"
+(void)addCommentSectionIntoMonitoringReport:(NSString*)DBCommentName:(NSString*)keyName:(NSManagedObject*)outerObjectToDB:(NSDictionary *)monitoring_report;
but when I add:
#import "AppDelegate.h"
it works fine. Can you tell me why? What does AppDelegate has to do with NSManagedObject type?
Are you #importing <CoreData/CoreData.h> in your .h?
First, your method is a class method (+ sign).
Second, your method signature requires knowledge of NSManagedObject and NSDictionary.
Since those are the only elements requiring "external" knowledge, I'd wager AppDelegate.h contains imports of one of these.
I just tested your method by pasting it into one of my classes that imports headers that import CoreData. It builds fine, except it's marked as "unimplemented" ;)
I'm doing a dots game on the iphone for fun ( just simulator) and learning.
this is the game where there are dots and you connect them with "pathways", if you close the square that 4 dots create, you "win" the square.
Now I'm getting some warnings and I'd like to understand how to remove them.
First this is te situation.
I have a class that represents the connection between 2dots, called Pathway.
I have a class called circuit that represent the circuit created by 4 pathways.
so class Circuit has an NSMUtable array of 4 Pathways
and each pathway has an NSMutable array of at most 2 circuits ( each pathway can belong to at the most 2 circuits).
So as you can see there is an import cycle.
I used the #class to include on one of the classes the other because otherwise I'd get errors on compile.
It all works but I'm getting warnings on one of the classes because it can't see the methods for the other.
how can I work around this and what is the proper way to work with these kinds of problems.
File pathway.h
#class Circuit;
#interface Pathway {
}
...
#end;
File pathway.m
#import "circuit.h"
#import "pathway.h"
...
File circuit.h
#class Pathway;
#interface Circuit {
}
...
#end;
File circuit.m
#import "pathway.h"
#import "circuit.h"
...
You don't usually need the full declaration of a dependent class in the header declaring another class. You need the declaration in the implementation files, though. So, split things up.
Import the header file of the respective other class in your .m file. Use the #class directive in your .h file to be able to refer to the classes there.