Warning: Cannot modify header information - headers already sent
Happens when your script tries to send an HTTP header to the client but there already was output before, which resulted in headers to be already sent to the client.
This is an E_WARNING
and it will not stop the script.
A typical example would be a template file like this:
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
The session_start()
function will try to send headers with the session cookie to the client. But PHP already sent headers when it wrote the <html>
element to the output stream. You'd have to move the session_start()
to the top.
You can solve this by going through the lines before the code triggering the Warning and check where it outputs. Move any header sending code before that code.
An often overlooked output is new lines after PHP's closing ?>
. It is considered a standard practice to omit ?>
when it is the last thing in the file. Likewise, another common cause for this warning is when the opening <?php
has an empty space, line, or invisible character before it, causing the web server to send the headers and the whitespace/newline thus when PHP starts parsing won't be able to submit any header.
If your file has more than one <?php ... ?>
code block in it, you should not have any spaces in between them. (Note: You might have multiple blocks if you had code that was automatically constructed)
Also make sure you don't have any Byte Order Marks in your code, for example when the encoding of the script is UTF-8 with BOM.
Related Questions:
Using Objective-C Classes in Swift
If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit #import <Foundation/Foundation.h
to an older Objective-C File.)
Step 1: Add Objective-C Implementation -- .m
Add a .m
file to your class, and name it CustomObject.m
.
Step 2: Add Bridging Header
When adding your .m
file, you'll likely be hit with a prompt that looks like this:
Click Yes!
If you did not see the prompt, or accidentally deleted your bridging header, add a new .h
file to your project and name it <#YourProjectName#>-Bridging-Header.h
.
In some situations, particularly when working with Objective-C frameworks, you don't add an Objective-C class explicitly and Xcode can't find the linker. In this case, create your .h
file named as mentioned above, then make sure you link its path in your target's project settings like so:
Note:
It's best practice to link your project using the $(SRCROOT)
macro so that if you move your project, or work on it with others using a remote repository, it will still work. $(SRCROOT)
can be thought of as the directory that contains your .xcodeproj file. It might look like this:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
Step 3: Add Objective-C Header -- .h
Add another .h
file and name it CustomObject.h
.
Step 4: Build your Objective-C Class
In CustomObject.h
#import <Foundation/Foundation.h>
@interface CustomObject : NSObject
@property (strong, nonatomic) id someProperty;
- (void) someMethod;
@end
In CustomObject.m
#import "CustomObject.h"
@implementation CustomObject
- (void) someMethod {
NSLog(@"SomeMethod Ran");
}
@end
Step 5: Add Class to Bridging-Header
In YourProject-Bridging-Header.h
:
#import "CustomObject.h"
Step 6: Use your Object
In SomeSwiftFile.swift
:
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
There is no need to import explicitly; that's what the bridging header is for.
Using Swift Classes in Objective-C
Step 1: Create New Swift Class
Add a .swift
file to your project, and name it MySwiftObject.swift
.
In MySwiftObject.swift
:
import Foundation
@objc(MySwiftObject)
class MySwiftObject : NSObject {
@objc
var someProperty: AnyObject = "Some Initializer Val" as NSString
init() {}
@objc
func someFunction(someArg: Any) -> NSString {
return "You sent me \(someArg)"
}
}
Step 2: Import Swift Files to ObjC Class
In SomeRandomClass.m
:
#import "<#YourProjectName#>-Swift.h"
The file:<#YourProjectName#>-Swift.h
should already be created automatically in your project, even if you can not see it.
Step 3: Use your class
MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];
NSLog(@"RetString: %@", retString);
Notes:
If Code Completion isn't behaving as you expect, try running a quick build with ⌘⇧R to help Xcode find some of the Objective-C code from a Swift context and vice versa.
If you add a .swift
file to an older project and get the error dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, try completely restarting Xcode.
While it was originally possible to use pure Swift classes (Not descendents of NSObject
) which are visible to Objective-C by using the @objc
prefix, this is no longer possible. Now, to be visible in Objective-C, the Swift object must either be a class conforming to NSObjectProtocol
(easiest way to do this is to inherit from NSObject
), or to be an enum
marked @objc
with a raw value of some integer type like Int
. You may view the edit history for an example of Swift 1.x code using @objc
without these restrictions.
Best Answer
As described in the Xcode 8 beta 6 release notes,
In your case:
You can provide even more information if the error is converted to
NSError
(which is always possible):By adopting the
CustomNSError
protocol the error can provide auserInfo
dictionary (and also adomain
andcode
). Example: